From ca5383cfe561afe80b20cfbb7ac7cc0f4e6c429c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Oct 2003 17:00:09 +0400 Subject: [PATCH] fix for one of the bugs spotted by #1274 sql/sql_select.cc: back to the bug #1274: the following query EXPLAIN SELECT SQL_CALC_FOUND_ROWS race_name FROM races WHERE race_name LIKE '%Madison%' ORDER BY race_date DESC LIMIT 0,100 +-------+------+---------------+------+---------+------+--------+-----------------------------+ | table | type | possible_keys | key | key_len | ref | rows | Extra | +-------+------+---------------+------+---------+------+--------+-----------------------------+ | races | ALL | NULL | NULL | NULL | NULL | 505821 | Using where; Using filesort | +-------+------+---------------+------+---------+------+--------+-----------------------------+ The query returns no rows. There are two problems with it: - wrong access plan is chosed (sequential index scan in reverse order, which is VERY SLOW in case of MyISAM table + packed keys) It's wrong, because it doesn't take into account that SQL_CALC_FOUND_ROWS is present, in other words, is based on assumtion that LIMIT clause decrease number of rows to access significantly, which is not true as all rows are accessed. - the access plan is not shown in the EXPLAIN (bug #1560). I'm not fixing it here --- sql/sql_select.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 353a4623962..f1ab998c0fa 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -968,10 +968,20 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, } } } + /* + Here we sort rows for ORDER BY/GROUP BY clause, if the optimiser + chose FILESORT to be faster than INDEX SCAN or there is no + suitable index present. + Note, that create_sort_index calls test_if_skip_sort_order and may + finally replace sorting with index scan if there is a LIMIT clause in + the query. XXX: it's never shown in EXPLAIN! + OPTION_FOUND_ROWS supersedes LIMIT and is taken into account. + */ if (create_sort_index(&join.join_tab[join.const_tables], group ? group : order, select_limit, - thd->select_limit)) + join.select_options & OPTION_FOUND_ROWS ? + HA_POS_ERROR : thd->select_limit)) goto err; } join.having=having; // Actually a parameter