Sample Header Ad - 728x90

Help inconsistent index result on generated column after server restart

0 votes
1 answer
69 views
I have a table that has a date column and I need a data that will be group by week. And I found this Youtube video that used an index generated column Faster database indexes (straight from the docs) from PlanetScale. Then I modify my table to look like this.
mysql> show create table tbl_bought_code\G;
*************************** 1. row ***************************
       Table: tbl_bought_code
Create Table: CREATE TABLE tbl_bought_code (
  id int unsigned NOT NULL AUTO_INCREMENT,
  user_id int unsigned NOT NULL,
  package_code char(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  package_type tinyint NOT NULL,
  code_price int NOT NULL,
  bought_on date NOT NULL,
  bought_on_week int GENERATED ALWAYS AS (yearweek(bought_on,0)) VIRTUAL, -- this column was added
  PRIMARY KEY (id),
  UNIQUE KEY package_code (package_code),
  KEY user_id (user_id),
  KEY bought_on (bought_on), -- this index is added
  KEY bought_on_week_index (bought_on_week), -- this  index is also added
  CONSTRAINT tbl_bought_code_ibfk_1 FOREIGN KEY (user_id) REFERENCES tbl_users (id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=47348 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
Then I did this explain query
explain 
select sum(code_price), bought_on_week 
from tbl_bought_code 
where bought_on between DATE_FORMAT(DATE_ADD(NOW(), INTERVAL -6 MONTH),'%Y-%m-01') and NOW() 
group by bought_on_week;
And the result is very promising.
+----+-------------+-----------------+------------+-------+--------------------------------+-----------+---------+------+------+----------+----------------------------------------+
| id | select_type | table           | partitions | type  | possible_keys                  | key       | key_len | ref  | rows | filtered | Extra                                  |
+----+-------------+-----------------+------------+-------+--------------------------------+-----------+---------+------+------+----------+----------------------------------------+
|  1 | SIMPLE      | tbl_bought_code | NULL       | range | bought_on,bought_on_week_index | bought_on | 3       | NULL | 6962 |   100.00 | Using index condition; Using temporary |
+----+-------------+-----------------+------------+-------+--------------------------------+-----------+---------+------+------+----------+----------------------------------------+
But when I **restart** the server, and re execute the explain query I got this.
+----+-------------+-----------------+------------+-------+--------------------------------+----------------------+---------+------+-------+----------+-------------+
| id | select_type | table           | partitions | type  | possible_keys                  | key                  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+-----------------+------------+-------+--------------------------------+----------------------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | tbl_bought_code | NULL       | index | bought_on,bought_on_week_index | bought_on_week_index | 5       | NULL | 46274 |    15.05 | Using where |
+----+-------------+-----------------+------------+-------+--------------------------------+----------------------+---------+------+-------+----------+-------------+
Why the explain result is different after restarting the server? Why it uses the bought_on_week_index index instead of bought_on index? The first explain query only returns 6962 rows while the second explain query returns 46274, it look like it do a full table scan.
Asked by zer09 (463 rep)
Jan 11, 2024, 02:59 AM
Last activity: Jan 11, 2024, 10:26 PM