Bug #70341 | Key lengths lead to incomplete result sets; unhinted scans prefer such indexes | ||
---|---|---|---|
Submitted: | 13 Sep 2013 19:00 | Modified: | 1 Nov 2013 9:45 |
Reporter: | Arthur O'Dwyer | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
Version: | 5.5.31, 5.6 | OS: | Any |
Assigned to: | Jørgen Løland | CPU Architecture: | Any |
[13 Sep 2013 19:00]
Arthur O'Dwyer
[13 Sep 2013 23:25]
MySQL Verification Team
Thank you for the bug report. c:\dbs>net start mysqld56 The MySQLD56 service is starting.. The MySQLD56 service was started successfully. c:\dbs>56 c:\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 > create database yy; Query OK, 1 row affected (0.02 sec) mysql 5.6 > use yy Database changed mysql 5.6 > create table t (id int, data text, index k3(data(3)), index k10(data(10))); Query OK, 0 rows affected (0.64 sec) mysql 5.6 > insert into t values (1,"banana1"); Query OK, 1 row affected (0.03 sec) mysql 5.6 > insert into t values (2,"banana2"); Query OK, 1 row affected (0.03 sec) mysql 5.6 > insert into t values (3,"banana3"); Query OK, 1 row affected (0.39 sec) mysql 5.6 > insert into t values (4,"banana4"); Query OK, 1 row affected (0.03 sec) mysql 5.6 > insert into t values (5,"banana5"); Query OK, 1 row affected (0.03 sec) mysql 5.6 > insert into t values (6,"banana6"); Query OK, 1 row affected (0.03 sec) mysql 5.6 > insert into t values (7,"banana7"); Query OK, 1 row affected (0.02 sec) mysql 5.6 > insert into t values (8,"banana8"); Query OK, 1 row affected (0.03 sec) mysql 5.6 > insert into t values (9,"banana9"); Query OK, 1 row affected (0.05 sec) mysql 5.6 > mysql 5.6 > select * from t where "banana3" < data and data < "banana7"; -- incorrectly returns the empty set Empty set (0.00 sec) mysql 5.6 > select * from t use index() where "banana3" < data and data < "banana7"; -- table scan produces correct results +------+---------+ | id | data | +------+---------+ | 4 | banana4 | | 5 | banana5 | | 6 | banana6 | +------+---------+ 3 rows in set (0.00 sec) mysql 5.6 > select * from t use index(k10) where "banana3" < data and data < "banana7"; -- Even choosing the other index would have produced correct results, in this case! +------+---------+ | id | data | +------+---------+ | 4 | banana4 | | 5 | banana5 | | 6 | banana6 | +------+---------+ 3 rows in set (0.00 sec) mysql 5.6 >
[2 Oct 2013 17:50]
Paul DuBois
Noted in 5.6.15, 5.7.3 changelogs. In some cases, range conditions over indexes defined on column prefixes returned incomplete result sets. (For example, SELECT ... WHERE 'abcdef1' < col_name AND col_name < 'abcdef9', where the index on col_name indexed only the first 6 characters.)
[2 Oct 2013 18:03]
Arthur O'Dwyer
@Paul: Does "Noted in x.y.z changelogs" mean that the bug has actually been fixed in version x.y.z? Same question in re bug number 69841. Lastly, does the absence of "5.5.z" in this bug's case mean that you're not fixing it for 5.5 at all, or just that the fix is still in progress? (Hoped-for answers: yes, yes, and in-progress.)
[3 Oct 2013 6:20]
Jørgen Løland
Arthur: Yes, "Noted in x.y.z changelogs" means that the bug has been fixed in these versions. The absence of 5.5.z means that it is not fixed there. There are no plans to fix this in MySQL 5.5.z as far as I know.
[4 Dec 2013 11:44]
Laurynas Biveinis
5.6$ bzr log -r 5479 ------------------------------------------------------------ revno: 5479 committer: Jorgen Loland <jorgen.loland@oracle.com> branch nick: mysql-5.6 timestamp: Mon 2013-09-30 12:27:07 +0200 message: BUG#17458273: KEY LENGTHS LEAD TO INCOMPLETE RESULT SETS; UNHINTED SCANS PREFER SUCH INDEXES Consider a table with an index over a prefix of column 'x' and a query with a range condition over 'x': CREATE TABLE (... INDEX (x(4))) SELECT ... WHERE 'foobar2' < x and x < 'foobar5'; The index will not be able to distinguish between rows with x-values like "foobar", "foobaz" or "foobar3" since only the first four characters ("foob") will be stored in the index. Since all rows with an x-value prefix "foob" look equal, the range optimizer has to translate '<' and '>' to '<=' and '>=', respectively, for such indexes. In this bug, only "'foobar2' < x" is correctly translated. Later, when key_and() is executed on the the two ranges "'foob' <= x" and "NULL < x < 'foob'", key_and() correctly finds that these ranges together form an impossible condition. The fix is to also translate '<' to '<=' for prefix indexes so that key_and() can ultimately create the range "'foob' <= x <= 'foob'".