Bug #36006 | Optimizer does table scan for select count(*) w/5.1.22, .23, not 5.0.51, 5.1.11 | ||
---|---|---|---|
Submitted: | 11 Apr 2008 20:43 | Modified: | 13 May 2008 19:56 |
Reporter: | Richard Bejtlich | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
Version: | 5.1.22, 5.1.23, 5.1.25-BK | OS: | FreeBSD (7.0) |
Assigned to: | Gleb Shchepa | CPU Architecture: | Any |
Tags: | regression |
[11 Apr 2008 20:43]
Richard Bejtlich
[12 Apr 2008 0:01]
Richard Bejtlich
I ran my tests with 5.1.22, 5.1.23, and 5.0.51a on one box to show the problem.
Attachment: example_on_one_box.txt (text/plain), 18.41 KiB.
[12 Apr 2008 7:30]
Valeriy Kravchuk
On 5.1.25-BK: mysql> select version(); +-----------+ | version() | +-----------+ | 5.1.25-rc | +-----------+ 1 row in set (0.01 sec) mysql> create table t_1(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MyISAM; Query OK, 0 rows affected (0.01 sec) mysql> create table t_2(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MyISAM; Query OK, 0 rows affected (0.01 sec) mysql> create table t_3(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MyISAM; Query OK, 0 rows affected (0.01 sec) mysql> create table t_merge(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MRG_MyISAM UNION=(t_1, t_2, t_3); Query OK, 0 rows affected (0.00 sec) mysql> insert into t_1 values (1,1), (1,2),(1,3), (1,4); Query OK, 4 rows affected (0.01 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> insert into t_2 values (2,1), (2,2),(2,3), (2,4); Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> insert into t_3 values (3,1), (3,2),(3,3), (3,4); Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> explain select count(*) from t_1; +----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away | +----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+ 1 row in set (0.01 sec) mysql> explain select count(*) from t_merge; +----+-------------+---------+-------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+-------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | t_merge | index | NULL | c1 | 5 | NULL | 12 | Using index | +----+-------------+---------+-------+---------------+------+---------+------+------+-------------+ 1 row in set (0.00 sec) On 5.0.60-BK: openxs@suse:~/dbs/5.0> 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 1 Server version: 5.0.60 Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> create table t_1(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MyISAM; Query OK, 0 rows affected (0.03 sec) mysql> create table t_2(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MyISAM; Query OK, 0 rows affected (0.01 sec) mysql> create table t_3(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MyISAM; Query OK, 0 rows affected (0.01 sec) mysql> create table t_merge(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MRG_MyISAM UNION=(t_1, t_2, t_3); Query OK, 0 rows affected (0.01 sec) mysql> insert into t_1 values (1,1), (1,2),(1,3), (1,4); Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> insert into t_2 values (2,1), (2,2),(2,3), (2,4); Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> insert into t_3 values (3,1), (3,2),(3,3), (3,4); Query OK, 4 rows affected (0.01 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> explain select count(*) from t_merge; +----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away | +----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+ 1 row in set (0.00 sec) So, this is a regression bug in optimizer of recent 5.1.x. Test case: create table t_1(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MyISAM; create table t_2(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MyISAM; create table t_3(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MyISAM; create table t_merge(c1 int, c2 int, key c1(c1), key c2(c2)) engine=MRG_MyISAM UNION=(t_1, t_2, t_3); insert into t_1 values (1,1), (1,2),(1,3), (1,4); insert into t_2 values (2,1), (2,2),(2,3), (2,4); insert into t_3 values (3,1), (3,2),(3,3), (3,4); explain select count(*) from t_1; explain select count(*) from t_merge;
[25 Apr 2008 21:48]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/46053 ChangeSet@1.2565, 2008-04-26 02:45:58+05:00, gshchepa@host.loc +8 -0 Fixed bug#36006: Optimizer does table scan for SELECT COUNT(*) for ENGINE=MRG_MYISAM (should be optimized out). Before WL#3281 MERGE engine had the HA_NOT_EXACT_COUNT flag unset, and it worked with COUNT optimization as desired. After the removal of the HA_NOT_EXACT_COUNT flag neither HA_STATS_RECORDS_IS_EXACT (opposite to former HA_NOT_EXACT_COUNT flag) nor modern HA_HAS_RECORDS flag were not added to MERGE table flag mask. 1. The HA_HAS_RECORDS table flag has been set. 2. The ha_myisammrg::records method has been overridden to calculate total number of records in underlying tables.
[1 May 2008 6:16]
Bugs System
Pushed into 5.1.25-rc
[1 May 2008 6:18]
Bugs System
Pushed into 6.0.6-alpha
[13 May 2008 19:56]
Paul DuBois
Noted in 5.1.25, 6.0.6 changelogs. The MERGE storage engine did a table scan for SELECT COUNT(*) statements when it could calculate the number of records from the underlying tables.
[8 Oct 2008 21:06]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/55830 2860 Gleb Shchepa 2008-10-09 Cleanup for closed bug #36006: Optimizer does table scan for select count(*) Unnecessary overloading of ha_myisammrg::records() and related stuff have been removed.