Bug #70245 | incorrect costing for range scan causes optimizer to choose incorrect index | ||
---|---|---|---|
Submitted: | 4 Sep 2013 21:45 | Modified: | 5 Sep 2013 16:57 |
Reporter: | trevor price | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
Version: | 5.6.13 | OS: | Linux (2.6.16.33-xenU x86_64) |
Assigned to: | Jørgen Løland | CPU Architecture: | Any |
Tags: | optimizer cost range_scan |
[4 Sep 2013 21:45]
trevor price
[4 Sep 2013 21:48]
trevor price
Query trace on 5.6.13
Attachment: querytrace.rtf (text/rtf), 15.75 KiB.
[4 Sep 2013 22:12]
trevor price
a zip file has been loaded that contains data allowing replication of the issue. the data file is bug-data-70245.zip
[4 Sep 2013 22:24]
trevor price
further demonstrate the wrong index is selected. Server version: 5.6.13-log MySQL Community Server (GPL) 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> flush status ; Query OK, 0 rows affected (0.00 sec) mysql> select audio_media_owner_id -> from audio_media_play -> where station_id = 3555 and audio_media_owner_type = 'STATION_CLIP' -> and audio_media_owner_id in (48901, 48900, 48903, 48902, 48897, 48893, 48892, 48896, 48895, 48899, 48898, 48894) -> and start_server_unix_timestamp >= 1378227067247 order by start_server_unix_timestamp desc -> \G ----snipped------ mysql> show session status like 'hand%' ; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Handler_commit | 1 | | Handler_delete | 0 | | Handler_discover | 0 | | Handler_external_lock | 2 | | Handler_mrr_init | 0 | | Handler_prepare | 0 | | Handler_read_first | 0 | | Handler_read_key | 12 | | Handler_read_last | 0 | | Handler_read_next | 11088 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 0 | | Handler_rollback | 0 | | Handler_savepoint | 0 | | Handler_savepoint_rollback | 0 | | Handler_update | 0 | | Handler_write | 0 | +----------------------------+-------+ now , forcing 5.6.13 to use the correct index mysql> flush status ; Query OK, 0 rows affected (0.00 sec) select audio_media_owner_id from audio_media_play use index ( station_id_start_server_unix_timestamp) where station_id = 3555 and audio_media_owner_type = 'STATION_CLIP' and audio_media_owner_id in (48901, 48900, 48903, 48902, 48897, 48893, 48892, 48896, 48895, 48899, 48898, 48894) and start_server_unix_timestamp >= 1378227067247 order by start_server_unix_timestamp desc ; ----snipped---- mysql> show session status like 'hand%' ; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Handler_commit | 1 | | Handler_delete | 0 | | Handler_discover | 0 | | Handler_external_lock | 2 | | Handler_mrr_init | 0 | | Handler_prepare | 0 | | Handler_read_first | 0 | | Handler_read_key | 1 | | Handler_read_last | 0 | | Handler_read_next | 0 | | Handler_read_prev | 1005 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 0 | | Handler_rollback | 0 | | Handler_savepoint | 0 | | Handler_savepoint_rollback | 0 | | Handler_update | 0 | | Handler_write | 0 | +----------------------------+-------+ so that's 1,000 read_prev for the correct index and 11,000 read_next for the index chosen by 5.6.13
[5 Sep 2013 8:58]
Jørgen Løland
Hi Trevor, MySQL 5.6 has a new variable called eq_range_index_dive_limit. It determines whether or not to do a. expensive but accurate statistics gathering, or b. cheap but less accurate statistics gathering for conditions that can be translated to equality predicates (e.g. IN). The value is the maximum number of ranges there can be before we switch from a. to b. The default value is 10, and in your query you have 12 ranges, which in turn means that method b. is chosen. If you set eq_range_index_dive_limit to something greater than 12 or 0 (a. is always used) you should get the <5.6 behavior back. I'll close the bug - please reopen it if the suggestion above does not work for you.
[5 Sep 2013 16:57]
trevor price
yes, changing the variable specified changes the optimizer plan. Thanks.