Skip to content

Commit

Permalink
MDEV-8954 unnecessary fetch of entire table
Browse files Browse the repository at this point in the history
Merged fix into 10.2.
  • Loading branch information
Jacob Mathew committed May 1, 2017
1 parent 5ccaabe commit 7afcee4
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 0 deletions.
80 changes: 80 additions & 0 deletions storage/spider/ha_spider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2109,6 +2109,7 @@ int ha_spider::index_read_map_internal(
result_list.desc_flg = FALSE;
result_list.sorted = TRUE;
result_list.key_info = &table->key_info[active_index];
check_distinct_key_query();
result_list.limit_num =
result_list.internal_limit >= result_list.split_read ?
result_list.split_read : result_list.internal_limit;
Expand Down Expand Up @@ -2624,6 +2625,7 @@ int ha_spider::index_read_last_map_internal(
result_list.desc_flg = TRUE;
result_list.sorted = TRUE;
result_list.key_info = &table->key_info[active_index];
check_distinct_key_query();
result_list.limit_num =
result_list.internal_limit >= result_list.split_read ?
result_list.split_read : result_list.internal_limit;
Expand Down Expand Up @@ -3089,6 +3091,7 @@ int ha_spider::index_first_internal(
result_list.sorted = TRUE;
result_list.key_info = &table->key_info[active_index];
result_list.key_order = 0;
check_distinct_key_query();
result_list.limit_num =
result_list.internal_limit >= result_list.split_read ?
result_list.split_read : result_list.internal_limit;
Expand Down Expand Up @@ -3472,6 +3475,7 @@ int ha_spider::index_last_internal(
result_list.sorted = TRUE;
result_list.key_info = &table->key_info[active_index];
result_list.key_order = 0;
check_distinct_key_query();
result_list.limit_num =
result_list.internal_limit >= result_list.split_read ?
result_list.split_read : result_list.internal_limit;
Expand Down Expand Up @@ -3914,6 +3918,7 @@ int ha_spider::read_range_first_internal(
result_list.desc_flg = FALSE;
result_list.sorted = sorted;
result_list.key_info = &table->key_info[active_index];
check_distinct_key_query();
result_list.limit_num =
result_list.internal_limit >= result_list.split_read ?
result_list.split_read : result_list.internal_limit;
Expand Down Expand Up @@ -12077,6 +12082,81 @@ void ha_spider::check_direct_order_limit()
DBUG_VOID_RETURN;
}

/********************************************************************
* Check whether the current query is a SELECT DISTINCT using an
* index in a non-partitioned Spider configuration, with a
* projection list that consists solely of the first key prefix
* column.
*
* For a SELECT DISTINCT query using an index in a non-partitioned
* Spider configuration, with a projection list that consists
* solely of the first key prefix, set the internal row retrieval
* limit to avoid visiting each row multiple times.
********************************************************************/
void ha_spider::check_distinct_key_query()
{
DBUG_ENTER( "ha_spider::check_distinct_key_query" );

if ( result_list.direct_distinct && !partition_handler_share->handlers &&
result_list.keyread && result_list.check_direct_order_limit )
{
// SELECT DISTINCT query using an index in a non-partitioned configuration
KEY_PART_INFO* key_part = result_list.key_info->key_part;
Field* key_field = key_part->field;

if ( is_sole_projection_field( key_field->field_index ) )
{
// Projection list consists solely of the first key prefix column

// Set the internal row retrieval limit to avoid visiting each row
// multiple times. This fixes a Spider performance bug that
// caused each row to be visited multiple times.
result_list.internal_limit = 1;
}
}

DBUG_VOID_RETURN;
}

/********************************************************************
* Determine whether the current query's projection list
* consists solely of the specified column.
*
* Params IN - field_index:
* Field index of the column of interest within
* its table.
*
* Returns TRUE - if the query's projection list consists
* solely of the specified column.
* FALSE - otherwise.
********************************************************************/
bool ha_spider::is_sole_projection_field( uint16 field_index )
{
// NOTE: It is assumed that spider_db_append_select_columns() has already been called
// to build the bitmap of projection fields
bool is_ha_sole_projection_field;
uint loop_index, dbton_id;
spider_db_handler* dbton_hdl;
DBUG_ENTER( "ha_spider::is_sole_projection_field" );

for ( loop_index = 0; loop_index < share->use_sql_dbton_count; loop_index++ )
{
dbton_id = share->use_sql_dbton_ids[ loop_index ];
dbton_hdl = dbton_handler[ dbton_id ];

if ( dbton_hdl->first_link_idx >= 0 )
{
is_ha_sole_projection_field = dbton_hdl->is_sole_projection_field( field_index );
if ( !is_ha_sole_projection_field )
{
DBUG_RETURN( FALSE );
}
}
}

DBUG_RETURN( TRUE );
}

int ha_spider::check_ha_range_eof()
{
DBUG_ENTER("ha_spider::check_ha_range_eof");
Expand Down
2 changes: 2 additions & 0 deletions storage/spider/ha_spider.h
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,8 @@ class ha_spider: public handler
);
uint check_partitioned();
void check_direct_order_limit();
void check_distinct_key_query();
bool is_sole_projection_field( uint16 field_index );
int check_ha_range_eof();
int drop_tmp_tables();
bool handler_opened(
Expand Down
9 changes: 9 additions & 0 deletions storage/spider/spd_db_handlersocket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4994,6 +4994,15 @@ int spider_handlersocket_handler::append_explain_select_part(
DBUG_RETURN(0);
}

int spider_handlersocket_handler::is_sole_projection_field(
uint16 field_index
) {
DBUG_ENTER("spider_handlersocket_handler::is_sole_projection_field");
DBUG_PRINT("info", ("spider this=%p", this));
DBUG_ASSERT(0);
DBUG_RETURN(0);
}

bool spider_handlersocket_handler::is_bulk_insert_exec_period(
bool bulk_end
) {
Expand Down
3 changes: 3 additions & 0 deletions storage/spider/spd_db_handlersocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,9 @@ class spider_handlersocket_handler: public spider_db_handler
ulong sql_type,
int link_idx
);
bool is_sole_projection_field(
uint16 field_index
);
bool is_bulk_insert_exec_period(
bool bulk_end
);
Expand Down
3 changes: 3 additions & 0 deletions storage/spider/spd_db_include.h
Original file line number Diff line number Diff line change
Expand Up @@ -1279,6 +1279,9 @@ class spider_db_handler
ulong sql_type,
int link_idx
) = 0;
virtual bool is_sole_projection_field(
uint16 field_index
) = 0;
virtual bool is_bulk_insert_exec_period(
bool bulk_end
) = 0;
Expand Down
59 changes: 59 additions & 0 deletions storage/spider/spd_db_mysql.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9516,6 +9516,65 @@ int spider_mysql_handler::append_explain_select(
DBUG_RETURN(0);
}

/********************************************************************
* Determine whether the current query's projection list
* consists solely of the specified column.
*
* Params IN - field_index:
* Field index of the column of interest within
* its table.
*
* Returns TRUE - if the query's projection list consists
* solely of the specified column.
* FALSE - otherwise.
********************************************************************/
bool spider_mysql_handler::is_sole_projection_field( uint16 field_index )
{
// Determine whether the projection list consists solely of the field of interest
bool is_field_in_projection_list = FALSE;
TABLE* table = spider->get_table();
uint16 projection_field_count = 0;
uint16 projection_field_index;
Field** field;
DBUG_ENTER( "spider_mysql_handler::is_sole_projection_field" );

for ( field = table->field; *field ; field++ )
{
projection_field_index = ( *field )->field_index;

if ( !( minimum_select_bit_is_set( projection_field_index ) ) )
{
// Current field is not in the projection list
continue;
}

projection_field_count++;

if ( !is_field_in_projection_list )
{
if ( field_index == projection_field_index )
{
// Field of interest is in the projection list
is_field_in_projection_list = TRUE;
}
}

if ( is_field_in_projection_list && ( projection_field_count != 1 ) )
{
// Field of interest is not the sole column in the projection list
DBUG_RETURN( FALSE );
}
}

if ( is_field_in_projection_list && ( projection_field_count == 1 ) )
{
// Field of interest is the only column in the projection list
DBUG_RETURN( TRUE );
}

DBUG_RETURN( FALSE );
}

bool spider_mysql_handler::is_bulk_insert_exec_period(
bool bulk_end
) {
Expand Down
3 changes: 3 additions & 0 deletions storage/spider/spd_db_mysql.h
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,9 @@ class spider_mysql_handler: public spider_db_handler
ulong sql_type,
int link_idx
);
bool is_sole_projection_field(
uint16 field_index
);
bool is_bulk_insert_exec_period(
bool bulk_end
);
Expand Down
59 changes: 59 additions & 0 deletions storage/spider/spd_db_oracle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9571,6 +9571,65 @@ int spider_oracle_handler::append_explain_select(
DBUG_RETURN(0);
}

/********************************************************************
* Determine whether the current query's projection list
* consists solely of the specified column.
*
* Params IN - field_index:
* Field index of the column of interest within
* its table.
*
* Returns TRUE - if the query's projection list consists
* solely of the specified column.
* FALSE - otherwise.
********************************************************************/
bool spider_oracle_handler::is_sole_projection_field( uint16 field_index )
{
// Determine whether the projection list consists solely of the field of interest
bool is_field_in_projection_list = FALSE;
TABLE* table = spider->get_table();
uint16 projection_field_count = 0;
uint16 projection_field_index;
Field** field;
DBUG_ENTER( "spider_oracle_handler::is_sole_projection_field" );

for ( field = table->field; *field; field++ )
{
projection_field_index = ( *field )->field_index;

if ( !( minimum_select_bit_is_set( projection_field_index ) ) )
{
// Current field is not in the projection list
continue;
}

projection_field_count++;

if ( !is_field_in_projection_list )
{
if (field_index == projection_field_index)
{
// Field of interest is in the projection list
is_field_in_projection_list = TRUE;
}
}

if ( is_field_in_projection_list && ( projection_field_count != 1 ) )
{
// Field of interest is not the sole column in the projection list
DBUG_RETURN( FALSE );
}
}

if ( is_field_in_projection_list && ( projection_field_count == 1 ) )
{
// Field of interest is the only column in the projection list
DBUG_RETURN( TRUE );
}

DBUG_RETURN( FALSE );
}

bool spider_oracle_handler::is_bulk_insert_exec_period(
bool bulk_end
) {
Expand Down
3 changes: 3 additions & 0 deletions storage/spider/spd_db_oracle.h
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,9 @@ class spider_oracle_handler: public spider_db_handler
ulong sql_type,
int link_idx
);
bool is_sole_projection_field(
uint16 field_index
);
bool is_bulk_insert_exec_period(
bool bulk_end
);
Expand Down

0 comments on commit 7afcee4

Please sign in to comment.