Bug #9523 | abuse of index in simple query | ||
---|---|---|---|
Submitted: | 31 Mar 2005 13:15 | Modified: | 14 Jan 2010 16:40 |
Reporter: | Vadim Tkachenko | Email Updates: | |
Status: | No Feedback | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
Version: | 5.0.9-beta, 4.1.10a | OS: | Windows (Windows XP) |
Assigned to: | CPU Architecture: | Any |
[31 Mar 2005 13:15]
Vadim Tkachenko
[11 May 2005 16:46]
Igor Babaev
Employing a primitive cost model the optimizer sometimes selects not the fastest execution plan.
[19 Jul 2005 18:36]
Vadim Tkachenko
I checked optimizer behavior with extremally simple test case: CREATE TABLE `t2` ( `ID` int(11) default NULL, `ID1` int(11) default NULL, `SUBNAME` varchar(32) default NULL, KEY `ID1` (`ID1`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 SELECT cnt2 / cnt1 FROM (SELECT count(*) cnt1 FROM t2) d1, (SELECT count(*) cnt2 FROM t2 WHERE ID1=1) d2; 0.9492 = 94.92% mysql> EXPLAIN SELECT COUNT(SUBNAME) FROM t2 WHERE ID1=1; +----+-------------+-------+------+---------------+------+---------+-------+-------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+-------+-------+-------------+ | 1 | SIMPLE | t2 | ref | ID1 | ID1 | 5 | const | 81371 | Using where | +----+-------------+-------+------+---------------+------+---------+-------+-------+-------------+ i.e. optimizer wants to use index. execution time: SELECT COUNT(SUBNAME) FROM t2 WHERE ID1=1 - 1200 ms SELECT COUNT(SUBNAME) FROM t2 IGNORE INDEX (ID1) WHERE ID1=1 - 260 ms I think, whatever primitive optimizer we have, it should make right choice in this extremally simple case.
[2 Aug 2005 14:56]
Vadim Tkachenko
In case with 99% (for table with 1 000 000 rows) selectivity mysql> select c1/c2 from (select count(*) c1 from test.t2 where ID1=1) t1, (select count(*) c2 from test.t2) t2; +--------+ | c1/c2 | +--------+ | 0.9901 | +--------+ still mysql> explain select count(SUBNAME) from test.t2 where ID1=1\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t2 type: ref possible_keys: ID1 key: ID1 key_len: 5 ref: const rows: 918909 Extra: Using where In case with 100% selectivity tablescan is used.
[14 Dec 2009 16:40]
Valeriy Kravchuk
With recent mysql-6.0-codebase we have: 77-52-7-73:6.0-codebase openxs$ bin/mysql -uroot test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 6.0.14-alpha-debug Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> CREATE TABLE `t2` ( -> `ID` int(11) default NULL, -> `ID1` int(11) default NULL, -> `SUBNAME` varchar(32) default NULL, -> KEY `ID1` (`ID1`) -> ) ENGINE=MyISAM; Query OK, 0 rows affected (0.07 sec) mysql> insert into t2 values(rand()*10000, 1, ''); Query OK, 1 row affected (0.38 sec) mysql> insert into t2 select rand()*10000, 1, '' from t2 -> ; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> insert into t2 select rand()*10000, 1, '' from t2; Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> insert into t2 select rand()*10000, 1, '' from t2; Query OK, 4 rows affected (0.01 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> insert into t2 select rand()*10000, 1, NULL from t2; Query OK, 8 rows affected (0.02 sec) Records: 8 Duplicates: 0 Warnings: 0 mysql> insert into t2 select rand()*10000, 1, NULL from t2; Query OK, 16 rows affected (0.01 sec) Records: 16 Duplicates: 0 Warnings: 0 mysql> insert into t2 select rand()*10000, 1, NULL from t2; Query OK, 32 rows affected (0.00 sec) Records: 32 Duplicates: 0 Warnings: 0 mysql> insert into t2 select rand()*10000, 1, NULL from t2; Query OK, 64 rows affected (0.01 sec) Records: 64 Duplicates: 0 Warnings: 0 mysql> insert into t2 select rand()*10000, 1, NULL from t2; Query OK, 128 rows affected (0.01 sec) Records: 128 Duplicates: 0 Warnings: 0 mysql> insert into t2 select rand()*10000, 2, 'a' from t2; Query OK, 256 rows affected (0.01 sec) Records: 256 Duplicates: 0 Warnings: 0 mysql> insert into t2 select rand()*10000, 1, 'a' from t2; Query OK, 512 rows affected (0.02 sec) Records: 512 Duplicates: 0 Warnings: 0 mysql> SELECT cnt2 / cnt1 FROM (SELECT count(*) cnt1 FROM t2) d1, (SELECT count(*) cnt2 FROM t2 -> WHERE ID1=1) d2; +-------------+ | cnt2 / cnt1 | +-------------+ | 0.7500 | +-------------+ 1 row in set (0.02 sec) mysql> EXPLAIN SELECT COUNT(SUBNAME) FROM t2 WHERE ID1=1; +----+-------------+-------+------+---------------+------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+-------+------+-------+ | 1 | SIMPLE | t2 | ref | ID1 | ID1 | 5 | const | 829 | | +----+-------------+-------+------+---------------+------+---------+-------+------+-------+ 1 row in set (0.36 sec) So, with 75% selectivity index is used. And maybe this is bad: mysql> SELECT COUNT(SUBNAME) FROM t2 WHERE ID1=1; +----------------+ | COUNT(SUBNAME) | +----------------+ | 520 | +----------------+ 1 row in set (0.01 sec) mysql> SELECT COUNT(SUBNAME) FROM t2 IGNORE INDEX (ID1) WHERE ID1=1; +----------------+ | COUNT(SUBNAME) | +----------------+ | 520 | +----------------+ 1 row in set (0.00 sec) mysql> SELECT COUNT(SUBNAME) FROM t2 WHERE ID1=1; +----------------+ | COUNT(SUBNAME) | +----------------+ | 520 | +----------------+ 1 row in set (0.01 sec) mysql> insert into t2 select rand()*10000, 1, NULL from t2;Query OK, 1024 rows affected (0.05 sec) Records: 1024 Duplicates: 0 Warnings: 0 mysql> insert into t2 select rand()*10000, 1, NULL from t2;Query OK, 2048 rows affected (0.11 sec) Records: 2048 Duplicates: 0 Warnings: 0 mysql> SELECT cnt2 / cnt1 FROM (SELECT count(*) cnt1 FROM t2) d1, (SELECT count(*) cnt2 FROM t2 WHERE ID1=1) d2; +-------------+ | cnt2 / cnt1 | +-------------+ | 0.9375 | +-------------+ 1 row in set (0.01 sec) mysql> insert into t2 select rand()*10000, 1, NULL from t2;Query OK, 4096 rows affected (0.24 sec) Records: 4096 Duplicates: 0 Warnings: 0 mysql> SELECT cnt2 / cnt1 FROM (SELECT count(*) cnt1 FROM t2) d1, (SELECT count(*) cnt2 FROM t2 WHERE ID1=1) d2; +-------------+ | cnt2 / cnt1 | +-------------+ | 0.9688 | +-------------+ 1 row in set (0.03 sec) mysql> EXPLAIN SELECT COUNT(SUBNAME) FROM t2 WHERE ID1=1; +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | t2 | ALL | ID1 | NULL | NULL | NULL | 8192 | Using where | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 1 row in set (0.00 sec) but when selectivity is 96.88% index is NOT used. Can we consider the problem solved?
[15 Jan 2010 0:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".