| Bug #70038 | Wrong select count distinct with a field included in two-column unique key | ||
|---|---|---|---|
| Submitted: | 14 Aug 2013 20:47 | Modified: | 19 Nov 2013 17:20 | 
| Reporter: | Michal Sulik | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) | 
| Version: | 5.5/5.6 | OS: | Any | 
| Assigned to: | CPU Architecture: | Any | |
| Tags: | COUNT DISTINCT, innodb, SELECT, unique key | ||
   [14 Aug 2013 20:47]
   Michal Sulik        
  
 
   [14 Aug 2013 21:27]
   MySQL Verification Team        
  Thank you for the bug report.
C:\dbs>c:\dbs\5.5\bin\mysql -uroot --port=3550 --prompt="mysql 5.5 > "
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.5.34 Source distribution
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql 5.5 > use test
Database changed
mysql 5.5 > CREATE TABLE tmp (
    ->   id int NOT NULL AUTO_INCREMENT,
    ->   a int NOT NULL,
    ->   b int NOT NULL,
    ->   PRIMARY KEY (id),
    ->   UNIQUE KEY ba (b, a)
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.11 sec)
<CUT>
mysql 5.5 >
mysql 5.5 > -- Returns 5, should return 10. Compare with previous queries.
mysql 5.5 > SELECT SQL_NO_CACHE COUNT(DISTINCT b) FROM tmp WHERE a = 1;
+-------------------+
| COUNT(DISTINCT b) |
+-------------------+
|                 5 |
+-------------------+
1 row in set (0.00 sec)
mysql 5.5 > alter table tmp drop index ba;
Query OK, 0 rows affected (0.11 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql 5.5 > SELECT SQL_NO_CACHE COUNT(DISTINCT b) FROM tmp WHERE a = 1;
+-------------------+
| COUNT(DISTINCT b) |
+-------------------+
|                10 |
+-------------------+
-------------------------------------------------------------------------------
1 roC:\dbs>c:\dbs\5.6\bin\mysql -uroot --port=3560 --prompt="mysql 5.6 > "
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.14 Source distribution
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql 5.6 > use test
Database changed
mysql 5.6 > CREATE TABLE tmp (
    ->   id int NOT NULL AUTO_INCREMENT,
    ->   a int NOT NULL,
    ->   b int NOT NULL,
    ->   PRIMARY KEY (id),
    ->   UNIQUE KEY ba (b, a)
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.38 sec)
<CUT>
mysql 5.6 >
mysql 5.6 > -- Returns 5, should return 10. Compare with previous queries.
mysql 5.6 > SELECT SQL_NO_CACHE COUNT(DISTINCT b) FROM tmp WHERE a = 1;
+-------------------+
| COUNT(DISTINCT b) |
+-------------------+
|                 5 |
+-------------------+
1 row in set (0.00 sec)
mysql 5.6 > alter table tmp drop index ba;
Query OK, 0 rows affected (0.13 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql 5.6 > SELECT SQL_NO_CACHE COUNT(DISTINCT b) FROM tmp WHERE a = 1;
+-------------------+
| COUNT(DISTINCT b) |
+-------------------+
|                10 |
+-------------------+
1 row in set (0.00 sec)w in set (0.00 sec)
---------------------------------------------------------------------------------
C:\dbs>c:\dbs\5.0\bin\mysql -uroot --port=3500 --prompt="mysql 5.0 > "
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.97-Win X64 Source distribution
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql 5.0 > use test
Database changed
mysql 5.0 > CREATE TABLE tmp (
    ->   id int NOT NULL AUTO_INCREMENT,
    ->   a int NOT NULL,
    ->   b int NOT NULL,
    ->   PRIMARY KEY (id),
    ->   UNIQUE KEY ba (b, a)
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.08 sec)
<CUT>
mysql 5.0 >
mysql 5.0 > -- Returns 5, should return 10. Compare with previous queries.
mysql 5.0 > SELECT SQL_NO_CACHE COUNT(DISTINCT b) FROM tmp WHERE a = 1;
+-------------------+
| COUNT(DISTINCT b) |
+-------------------+
|                10 |
+-------------------+
1 row in set (0.00 sec)
 
   [19 Aug 2013 13:54]
   Patryk Pomykalski        
  Looks like a bug in QUICK_GROUP_MIN_MAX_SELECT when is_index_scan is true (can skip half of the rows).
I think this can fix it:
=== modified file 'sql/opt_range.cc'
--- sql/opt_range.cc    2013-04-30 17:16:37 +0000
+++ sql/opt_range.cc    2013-08-19 13:43:51 +0000
@@ -11039,7 +11039,7 @@
       are equality predicates for the key parts after the group, find the
       first sub-group with the extended prefix.
     */
-    if (!have_min && !have_max && key_infix_len > 0)
+    if (!have_min && !have_max && key_infix_len > 0 && !is_index_scan)
       result= file->index_read_map(record, group_prefix,
                                    make_prev_keypart_map(real_key_parts),
                                    HA_READ_KEY_EXACT);
 
   [19 Aug 2013 19:39]
   Patryk Pomykalski        
  Myisam works, so maybe the above fix is incorrect.
   [2 Sep 2013 3:04]
   Guangpu Feng        
  Verified, this bug also affects Percona server 5.5.18.
   [17 Sep 2013 6:59]
   Guangpu Feng        
  Any progress?
   [17 Sep 2013 12:33]
   Mattias Jonsson        
  The patch is currently in review.
   [14 Nov 2013 13:00]
   Hartmut Holzgraefe        
  5.6 (tested with 5.6.14) is even worse, returns 100 on the last query instead of 200: SELECT SQL_NO_CACHE COUNT(DISTINCT b) FROM t1 WHERE a = 1; COUNT(DISTINCT b) -200 +100
   [19 Nov 2013 17:20]
   Daniel Price        
  This bug was addressed in a bug fix for a related bug (Oracle Bug#14621190). The fix is noted in 5.5.35, 5.6.15, and 5.7.3 changelogs. The changelog text for the duplicate bug, as noted in the 5.5.35, 5.6.15, and 5.7.3 changelogs, is: When "index_read_map" is called for an exact search and fails to return a record due to non-matching search criteria, the cursor would be positioned on the next record after the searched key. A subsequent call to "index_next " would return the next record instead of returning the previous non-matching row, thereby skipping a record. Thank you for the bug report.

