Bug #35088 index_merge query on partitioned MyISAM table returns incorrect results
Submitted: 5 Mar 2008 19:41 Modified: 5 Mar 2008 22:39
Reporter: Greg Smyth Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.1.22-rc-community-log OS:Any
Assigned to: CPU Architecture:Any
Tags: index_merge, partitioned, partitioning

[5 Mar 2008 19:41] Greg Smyth
Description:
Similar to Bug #29740, an incorrect result is returned from an index_merge query but this time it only occurs on partitioned tables.  I will post a test database that has data distributed across partitions that reproduces the error.  I tried tables of 100, 1000, and 10,000 rows and only could reproduce with the 10,000 row table.

How to repeat:
mysql> show variables like 'version%';
+-------------------------+-------------------------------+
| Variable_name           | Value                         |
+-------------------------+-------------------------------+
| version                 | 5.1.22-rc-community-log       |
| version_comment         | MySQL Community Edition (GPL) |
| version_compile_machine | i686                          |
| version_compile_os      | redhat-linux-gnu              |
+-------------------------+-------------------------------+
4 rows in set (0.00 sec)

mysql> explain select * from test_partitions where a=19372095 or b=19372095;
+----+-------------+-----------------+-------------+---------------+------+---------+------+------+-------------------------------+
| id | select_type | table           | type        | possible_keys | key  | key_len | ref  | rows | Extra                 |
+----+-------------+-----------------+-------------+---------------+------+---------+------+------+-------------------------------+
|  1 | SIMPLE      | test_partitions | index_merge | a,b           | a,b  | 4,4     | NULL |  190 | Using union(a,b); Using where |
+----+-------------+-----------------+-------------+---------------+------+---------+------+------+-------------------------------+
1 row in set (0.00 sec)

mysql> select count(*) from test_partitions where a=19372095 or b=19372095;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.01 sec)

mysql> explain select count(*) from test_partitions ignore index(a,b) where a=19372095 or b=19372095;
+----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table           | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | test_partitions | ALL  | NULL          | NULL | NULL    | NULL | 10000 | Using where |
+----+-------------+-----------------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)

mysql> select count(*) from test_partitions ignore index(a,b) where a=19372095 or b=19372095;
+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.00 sec)

mysql> CREATE TABLE test_no_partitions (     
    ->   anID bigint(20) unsigned NOT NULL auto_increment,     
    ->   ThisID tinyint(1) UNSIGNED NOT NULL,     
    ->   Timestamp int(10) unsigned NOT NULL,
    ->   a int(10) unsigned NOT NULL,
    ->   b int(10) unsigned NOT NULL,
    ->   PRIMARY KEY (anID,ThisID,Timestamp),
    ->   INDEX (ThisID),
    ->   INDEX (Timestamp),
    ->   INDEX (a),
    ->   INDEX (b)
    -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Query OK, 0 rows affected (0.01 sec)

mysql> insert test_no_partitions select * from test_partitions;
Query OK, 10000 rows affected (0.12 sec)
Records: 10000  Duplicates: 0  Warnings: 0

mysql> explain select * from test_no_partitions where a=19372095 or b=19372095;
+----+-------------+--------------------+-------------+---------------+------+---------+------+------+-------------------------------+
| id | select_type | table              | type        | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+-------------+--------------------+-------------+---------------+------+---------+------+------+-------------------------------+
|  1 | SIMPLE      | test_no_partitions | index_merge | a,b           | a,b  | 4,4     | NULL |    2 | Using union(a,b); Using where |
+----+-------------+--------------------+-------------+---------------+------+---------+------+------+-------------------------------+
1 row in set (0.00 sec)

mysql> select count(*) from test_no_partitions where a=19372095 or b=19372095;
+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.00 sec)

mysql>

Suggested fix:
Workaround is to not use partitioning, or force MySQL to ignore the offending indexes with "ignore index" as in the example.
[5 Mar 2008 19:44] Greg Smyth
Dump of the test_partitions table that reproduces the bug

Attachment: mysql_bug_index_partitions_data.sql (application/octet-stream, text), 412.78 KiB.

[5 Mar 2008 22:39] Sveta Smirnova
Thank you for the report.

I can not repeat described behavior with version 5.1.23, althoug with version 5.1.22 bug is repeatable. please upgrade.