Bug #100597 | INDEX hint does not affect count(*) execution | ||
---|---|---|---|
Submitted: | 21 Aug 2020 7:10 | Modified: | 16 Apr 2024 5:22 |
Reporter: | Øystein Grøvlen | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
Version: | 8.0 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[21 Aug 2020 7:10]
Øystein Grøvlen
[21 Aug 2020 7:16]
Øystein Grøvlen
I am sorry. I made a cut&paste error, so it did not show the query with hint. Here is what I wanted to show: mysql> EXPLAIN select /*+ INDEX(city CountryCode) */ count(*) from city; +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+ | 1 | SIMPLE | city | NULL | index | NULL | CountryCode | 3 | NULL | 4188 | 100.00 | Using index | +----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec) Note (Code 1003): /* select#1 */ select /*+ INDEX(`city`@`select#1` `CountryCode`) */ count(0) AS `count(*)` from `world`.`city` mysql> select /*+ INDEX(city CountryCode) */ count(*) from city; +----------+ | count(*) | +----------+ | 4079 | +----------+ 1 row in set (0.01 sec) mysql> select index_name, buf_count, stat_value leaf_pages, (100.00*buf_count)/stat_value percent from mysql.innodb_index_stats index_stats join (select index_name, count(*) buf_count from information_schema.innodb_buffer_page where table_name like '%city%' group by index_name) buf_stats using(index_name) where index_stats.table_name like 'city' and stat_name = 'n_leaf_pages' ; +------------+-----------+------------+------------+ | index_name | buf_count | leaf_pages | percent | +------------+-----------+------------+------------+ | PRIMARY | 25 | 24 | 104.166667 | +------------+-----------+------------+------------+ 1 row in set (4.97 sec)
[21 Aug 2020 12:37]
MySQL Verification Team
Hi Oystein, Thank you for your bug report. However, I do not think that I have got the same results as you. The only difference between your and my `world` schema is that `city` table has a column named 'Country`, but not `CountryCode`, although data are identical. I have first run your queries from the How-to-repeat section and then the additional queries with a hint. Here are my results: ========================================== d select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE city NULL index NULL Population 4 NULL 4079 100.00 Using index count(*) 4079 index_name buf_count leaf_pages percent PRIMARY 20 19 105.263158 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE city NULL index Country Country 12 NULL 4079 100.00 Using where; Using index count(*) 4079 index_name buf_count leaf_pages percent PRIMARY 20 19 105.263158 Country 7 6 116.666667 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE city NULL index NULL Population 4 NULL 4079 100.00 Using index count(*) 4079 index_name buf_count leaf_pages percent PRIMARY 20 19 105.263158 Country 7 6 116.666667
[22 Aug 2020 4:24]
Øystein Grøvlen
Hi! I am sorry I messed things up a bit. However, regarding the table definition, I downloaded the database from https://dev.mysql.com/doc/index-other.html, and the definition for city is: mysql> show create table city\G *************************** 1. row *************************** Table: city Create Table: CREATE TABLE `city` ( `ID` int NOT NULL AUTO_INCREMENT, `Name` char(35) NOT NULL DEFAULT '', `CountryCode` char(3) NOT NULL DEFAULT '', `District` char(20) NOT NULL DEFAULT '', `Population` int NOT NULL DEFAULT '0', PRIMARY KEY (`ID`), KEY `CountryCode` (`CountryCode`), CONSTRAINT `city_ibfk_1` FOREIGN KEY (`CountryCode`) REFERENCES `country` (`Code`) ) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec) The correct "How to repeat" should be: Start a new server (I set innodb_buffer_pool_load_at_startup=OFF in config file to make sure the table pages are not loaded) use world; select index_name, buf_count, stat_value leaf_pages, (100.00*buf_count)/stat_value percent from mysql.innodb_index_stats index_stats join (select index_name, count(*) buf_count from information_schema.innodb_buffer_page where table_name like '%city%' group by index_name) buf_stats using(index_name) where index_stats.table_name like 'city' and stat_name = 'n_leaf_pages' ; explain select /*+ INDEX(city CountryCode) */ count(*) from city; select /*+ INDEX(city CountryCode) */ count(*) from city; select index_name, buf_count, stat_value leaf_pages, (100.00*buf_count)/stat_value percent from mysql.innodb_index_stats index_stats join (select index_name, count(*) buf_count from information_schema.innodb_buffer_page where table_name like '%city%' group by index_name) buf_stats using(index_name) where index_stats.table_name like 'city' and stat_name = 'n_leaf_pages' ; explain select count(*) from city where countrycode < 'ZZZ'; select count(*) from city where countrycode < 'ZZZ'; select index_name, buf_count, stat_value leaf_pages, (100.00*buf_count)/stat_value percent from mysql.innodb_index_stats index_stats join (select index_name, count(*) buf_count from information_schema.innodb_buffer_page where table_name like '%city%' group by index_name) buf_stats using(index_name) where index_stats.table_name like 'city' and stat_name = 'n_leaf_pages' ;
[22 Aug 2020 4:27]
Øystein Grøvlen
That said, your results still illustrates part of the issue. EXPLAIN says it will use an index (Population in your case), but buffer pool contents shows that this index has not been used. My extra point is that even if a use a hint, the index will not be used.
[24 Aug 2020 12:24]
MySQL Verification Team
Hi Øystein , I have been using that innodb-...... option regularly, for the cases like this one. You are right about my previous results showing the problem again. With changed `world` schema, I am able to repeat fully the behaviour. Also, I agree that this is a low priority bug. Verified as reported.
[17 Feb 2024 3:26]
Rahul Sisondia
Posted by developer: This issue is fixed through Bug#35952353 SELECT COUNT(*) degraded performance on 8.0 compared to 5.7
[19 Feb 2024 12:36]
MySQL Verification Team
Thank you, Rahul ........
[16 Apr 2024 5:22]
MySQL Verification Team
This is marked as a duplicate of Bug#113482 [16 Feb 22:07] Philip Olson Posted by developer: Fixed as of the upcoming MySQL Server 8.0.37 and 8.4.0 releases, and here's the proposed changelog entry from the documentation team: A SELECT COUNT(*) query that used a secondary index for scanning would perform much slower than the same query did in MySQL 5.7. Thank you for the bug report.
[16 Apr 2024 10:18]
MySQL Verification Team
Thank you for your information.
[17 Apr 2024 22:37]
Philip Olson
Posted by developer: Release note updated and now reads as follows for both MySQL Bug #100597 and MySQL Bug #112767: MySQL no longer ignores the Optimizer hint to use a secondary index scan, which instead forced a clustered (parallel) index scan.
[18 Apr 2024 10:19]
MySQL Verification Team
Thank you, Philip.