1
0
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:
unknown
2007-07-20 21:05:29 +03:00
parent 56a65d7ad0
commit 95a8c6c327
4 changed files with 309 additions and 2 deletions

View File

@@ -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