From 2d4db52edac1488c9481b303095229b424288e64 Mon Sep 17 00:00:00 2001 From: Evgeny Potemkin Date: Fri, 26 Feb 2010 14:17:00 +0300 Subject: [PATCH] Bug#50843: Filesort used instead of clustered index led to performance degradation. Filesort + join cache combination is preferred to full index scan because it is usually faster. But it's not the case when the index is clustered one. Now test_if_skip_sort_order function prefers filesort only if index isn't clustered. mysql-test/r/innodb_mysql.result: Added a test case for the bug#50843. mysql-test/t/innodb_mysql.test: Added a test case for the bug#50843. sql/sql_select.cc: Bug#50843: Filesort used instead of clustered index led to performance degradation. Now test_if_skip_sort_order function prefers filesort only if index isn't clustered. --- mysql-test/r/innodb_mysql.result | 14 ++++++++++++++ mysql-test/t/innodb_mysql.test | 12 ++++++++++++ sql/sql_select.cc | 19 +++++++++++++------ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index b54fb90b412..c4279018cb8 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -2281,4 +2281,18 @@ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb ; SELECT 1 FROM t1 JOIN t1 a USING(a) GROUP BY t1.a,t1.a; 1 DROP TABLE t1; +# +# Bug#50843: Filesort used instead of clustered index led to +# performance degradation. +# +create table t1(f1 int not null primary key, f2 int) engine=innodb; +create table t2(f1 int not null, key (f1)) engine=innodb; +insert into t1 values (1,1),(2,2),(3,3); +insert into t2 values (1),(2),(3); +explain select t1.* from t1 left join t2 using(f1) group by t1.f1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 3 +1 SIMPLE t2 ref f1 f1 4 test.t1.f1 1 Using index +drop table t1,t2; +# End of 5.1 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index d9fecccfbdc..a3c11b8b8d6 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -545,5 +545,17 @@ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb ; SELECT 1 FROM t1 JOIN t1 a USING(a) GROUP BY t1.a,t1.a; DROP TABLE t1; +--echo # +--echo # Bug#50843: Filesort used instead of clustered index led to +--echo # performance degradation. +--echo # +create table t1(f1 int not null primary key, f2 int) engine=innodb; +create table t2(f1 int not null, key (f1)) engine=innodb; +insert into t1 values (1,1),(2,2),(3,3); +insert into t2 values (1),(2),(3); +explain select t1.* from t1 left join t2 using(f1) group by t1.f1; +drop table t1,t2; +--echo # + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 52f9aae7a0c..c4fac5b50ef 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13304,12 +13304,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, */ if (select_limit >= table_records) { - /* - filesort() and join cache are usually faster than reading in - index order and not using join cache - */ - if (tab->type == JT_ALL && tab->join->tables > tab->join->const_tables + 1) - DBUG_RETURN(0); keys= *table->file->keys_to_use_for_scanning(); keys.merge(table->covering_keys); @@ -13459,6 +13453,19 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, } } } + + /* + filesort() and join cache are usually faster than reading in + index order and not using join cache, except in case that chosen + index is clustered primary key. + */ + if ((select_limit >= table_records) && + (tab->type == JT_ALL && + tab->join->tables > tab->join->const_tables + 1) && + ((unsigned) best_key != table->s->primary_key || + !table->file->primary_key_is_clustered())) + DBUG_RETURN(0); + if (best_key >= 0) { bool quick_created= FALSE;