mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
Bug #28591: MySQL need not sort the records in case of
ORDER BY primary_key on InnoDB table Queries that use an InnoDB secondary index to retrieve data don't need to sort in case of ORDER BY primary key if the secondary index is compared to constant(s). They can also skip sorting if ORDER BY contains both the the secondary key parts and the primary key parts (in that order). This is because InnoDB returns the rows in order of the primary key for rows with the same values of the secondary key columns. Fixed by preventing temp table sort for the qualifying queries. mysql-test/r/innodb_mysql.result: Bug #28591: test case mysql-test/t/innodb_mysql.test: Bug #28591: test case sql/sql_select.cc: Bug #28591: Use the primary key as suffix when testing if the key can be used for ORDER BY on supporting engines. sql/table.cc: Bug #28591: can use the primary key as a suffix for the secondary keys
This commit is contained in:
@@ -12009,6 +12009,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
|
||||
key_part_end=key_part+table->key_info[idx].key_parts;
|
||||
key_part_map const_key_parts=table->const_key_parts[idx];
|
||||
int reverse=0;
|
||||
my_bool on_primary_key= FALSE;
|
||||
DBUG_ENTER("test_if_order_by_key");
|
||||
|
||||
for (; order ; order=order->next, const_key_parts>>=1)
|
||||
@@ -12023,7 +12024,30 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
|
||||
for (; const_key_parts & 1 ; const_key_parts>>= 1)
|
||||
key_part++;
|
||||
|
||||
if (key_part == key_part_end || key_part->field != field)
|
||||
if (key_part == key_part_end)
|
||||
{
|
||||
/*
|
||||
We are at the end of the key. Check if the engine has the primary
|
||||
key as a suffix to the secondary keys. If it has continue to check
|
||||
the primary key as a suffix.
|
||||
*/
|
||||
if (!on_primary_key &&
|
||||
(table->file->table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
|
||||
table->s->primary_key != MAX_KEY)
|
||||
{
|
||||
on_primary_key= TRUE;
|
||||
key_part= table->key_info[table->s->primary_key].key_part;
|
||||
key_part_end=key_part+table->key_info[table->s->primary_key].key_parts;
|
||||
const_key_parts=table->const_key_parts[table->s->primary_key];
|
||||
|
||||
for (; const_key_parts & 1 ; const_key_parts>>= 1)
|
||||
key_part++;
|
||||
}
|
||||
else
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
if (key_part->field != field)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
/* set flag to 1 if we can use read-next on key, else to -1 */
|
||||
@@ -12034,7 +12058,8 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
|
||||
reverse=flag; // Remember if reverse
|
||||
key_part++;
|
||||
}
|
||||
*used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
|
||||
*used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
|
||||
(uint) (key_part - table->key_info[idx].key_part);
|
||||
if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
|
||||
HA_READ_PREV))
|
||||
reverse= 0; // Index can't be used
|
||||
|
||||
Reference in New Issue
Block a user