Bug #108127 MySQL optimizer chooses to a inefficient index .
Submitted: 12 Aug 2022 5:57 Modified: 16 Aug 2022 12:36
Reporter: Lin TSE YU Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S5 (Performance)
Version:8.0.29 OS:Any
Assigned to: CPU Architecture:Any
Tags: covering index, INDEX, Optimizer

[12 Aug 2022 5:57] Lin TSE YU
Description:
Query :

This query has two possible keys ,idx_01 and idx_02 ,MySQL optimizer choose the idx_01 for this query ,because the idx_01 cost is less than idx_02 .
Actually choose idx_02 is better  and more fast than idx_01 ,because idx_02 is a cover index .So I think MySQL optimizer choose a wrong index .

mysql> show create table info2 \G;
*************************** 1. row ***************************
       Table: info2
Create Table: CREATE TABLE `info2` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `agent_id` int unsigned NOT NULL DEFAULT '0',
  `order_code` varchar(10) NOT NULL DEFAULT '',
  `issue` char(12) NOT NULL DEFAULT '',
  `order_number` varchar(700) NOT NULL DEFAULT '',
  `state` tinyint unsigned NOT NULL DEFAULT '0',
  `is_test` bit(1) NOT NULL DEFAULT b'0',
  `created_date` date NOT NULL DEFAULT '1970-01-01',
  PRIMARY KEY (`id`),
  KEY `idx_01` (`issue`),
  KEY `idx_02` (`order_code`,`issue`,`state`,`order_number`),
  KEY `idx_03` (`agent_id`),
  KEY `idx_05` (`created_date`,`is_test`,`order_code`,`state`)
) ENGINE=InnoDB AUTO_INCREMENT=98000002131317 DEFAULT CHARSET=utf8mb3
1 row in set (0.08 sec)

mysql> analyze table info2;
+-------------+---------+----------+----------+
| Table       | Op      | Msg_type | Msg_text |
+-------------+---------+----------+----------+
| jtest.info2 | analyze | status   | OK       |
+-------------+---------+----------+----------+
1 row in set (0.22 sec)

mysql> explain analyze
    -> select count(1)
    -> from info2  
    -> where order_code = '1027'
    ->  and issue = '20220720'
    ->  and state = 0 ;
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EXPLAIN                                                                                                                                                                                                                                                                                                                                                                                                  |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Aggregate: count(1)  (cost=35405.89 rows=1) (actual time=17378.759..17378.760 rows=1 loops=1)
    -> Filter: ((info2.state = 0) and (info2.order_code = '1027'))  (cost=34346.18 rows=10597) (actual time=306.768..17351.605 rows=426873 loops=1)
        -> Index lookup on info2 using idx_01 (issue='20220720')  (cost=34346.18 rows=1059712) (actual time=1.489..17092.348 rows=2000011 loops=1)
 |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (17.46 sec)

mysql> explain analyze
    -> select count(1)
    -> from info2 force index(idx_02)
    -> where order_code = '1027'
    ->  and issue = '20220720'
    ->  and state = 0 ;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EXPLAIN                                                                                                                                                                                                                                                                         |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Aggregate: count(1)  (cost=289747.99 rows=1) (actual time=935.811..935.812 rows=1 loops=1)
    -> Covering index lookup on info2 using idx_02 (order_code='1027', issue='20220720', state=0)  (cost=201099.79 rows=886482) (actual time=0.052..916.064 rows=426873 loops=1)
 |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.94 sec)

How to repeat:
1.Create the info2 table .

2.Import the info2.sql file . 

3.Run the two queries :
explain analyze
select count(1)
from info2
where order_code = '1027'
 and issue = '20220720'
 and state = 0 ;

explain analyze
select count(1)
from info2 force index(idx_02)
where order_code = '1027'
 and issue = '20220720'
 and state = 0 ;
[12 Aug 2022 6:03] Lin TSE YU
Attached the info2.sql file link
https://www.sendspace.com/file/qkcz9r
[12 Aug 2022 11:52] MySQL Verification Team
Hi Mr. Yu,

Thank you for your bug report.

Please, upload your SQL files to the "Files" tab in this report. If your file is too large, then please bzip it and try again. If your bzipped file is still too large, then upload to our SFTP server, as per the instructions.

Not enough information was provided for us to be able to handle this bug. Please re-read the instructions at http://bugs.mysql.com/how-to-report.php 

If you can provide more information, feel free to add it to this bug and change the status back to 'Open'.  

Thank you for your interest in MySQL.
[15 Aug 2022 6:16] Lin TSE YU
I have attached the mysql-bug-data-108127.zip file on SFTP .
[16 Aug 2022 12:23] MySQL Verification Team
Hi Mr. YU,

Can you, please, let us know in which directory have you uploaded that file ????
[16 Aug 2022 12:36] MySQL Verification Team
Hi Mr. YU,

No feedback is required from you.

We have downloaded your ZIP file and managed to repeat the behaviour.

We have managed to repeat the behaviour.

This reported is now a verified bug.

Thank you.