diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-05-05 16:12:54 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-05-05 16:12:54 +0400 |
commit | ac53b49b1be807f588aebd83883ec93b764f5d54 (patch) | |
tree | c86cbdb535eefb15e2077a7ac2ffaeff9d76955e /storage/spider | |
parent | 583b68e89961c35fa95a06c38988f82e33c73f4a (diff) | |
parent | db0917f68f2681882974afd53935aa8cba29c6b8 (diff) | |
download | mariadb-git-ac53b49b1be807f588aebd83883ec93b764f5d54.tar.gz |
Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext
Diffstat (limited to 'storage/spider')
-rw-r--r-- | storage/spider/ha_spider.cc | 80 | ||||
-rw-r--r-- | storage/spider/ha_spider.h | 2 | ||||
-rw-r--r-- | storage/spider/spd_db_handlersocket.cc | 9 | ||||
-rw-r--r-- | storage/spider/spd_db_handlersocket.h | 3 | ||||
-rw-r--r-- | storage/spider/spd_db_include.h | 3 | ||||
-rw-r--r-- | storage/spider/spd_db_mysql.cc | 59 | ||||
-rw-r--r-- | storage/spider/spd_db_mysql.h | 3 | ||||
-rw-r--r-- | storage/spider/spd_db_oracle.cc | 59 | ||||
-rw-r--r-- | storage/spider/spd_db_oracle.h | 3 |
9 files changed, 221 insertions, 0 deletions
diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index a87abfb8073..7ed8661cc74 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -12078,6 +12083,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"); diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index bd02e34043d..87c6afaa89f 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -751,6 +751,8 @@ public: ); 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( diff --git a/storage/spider/spd_db_handlersocket.cc b/storage/spider/spd_db_handlersocket.cc index 8f031acdbde..51b1d1f1752 100644 --- a/storage/spider/spd_db_handlersocket.cc +++ b/storage/spider/spd_db_handlersocket.cc @@ -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 ) { diff --git a/storage/spider/spd_db_handlersocket.h b/storage/spider/spd_db_handlersocket.h index d3fdf5564b7..a3955aea044 100644 --- a/storage/spider/spd_db_handlersocket.h +++ b/storage/spider/spd_db_handlersocket.h @@ -776,6 +776,9 @@ public: ulong sql_type, int link_idx ); + bool is_sole_projection_field( + uint16 field_index + ); bool is_bulk_insert_exec_period( bool bulk_end ); diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h index 936951d3860..56bc2ccad42 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -1279,6 +1279,9 @@ public: 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; diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index f902508e9c4..385b122c274 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -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 ) { diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h index 9a4f08ade98..482289d1d68 100644 --- a/storage/spider/spd_db_mysql.h +++ b/storage/spider/spd_db_mysql.h @@ -1128,6 +1128,9 @@ public: ulong sql_type, int link_idx ); + bool is_sole_projection_field( + uint16 field_index + ); bool is_bulk_insert_exec_period( bool bulk_end ); diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc index 5e6c89b10d0..5b322b9c4d7 100644 --- a/storage/spider/spd_db_oracle.cc +++ b/storage/spider/spd_db_oracle.cc @@ -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 ) { diff --git a/storage/spider/spd_db_oracle.h b/storage/spider/spd_db_oracle.h index 0e84435d9be..7a070f498da 100644 --- a/storage/spider/spd_db_oracle.h +++ b/storage/spider/spd_db_oracle.h @@ -1208,6 +1208,9 @@ public: ulong sql_type, int link_idx ); + bool is_sole_projection_field( + uint16 field_index + ); bool is_bulk_insert_exec_period( bool bulk_end ); |