假设我正在使用data
包含大约 1M 行的表运行 MySQL 8。我想过滤一个范围内的datetime
列date
(使用日期索引)。
CREATE TABLE `data` (
`rowId` int NOT NULL AUTO_INCREMENT,
`data` json NOT NULL,
`created` DATETIME NOT NULL, -- <-- datetime column for a date index
`created_date` DATE AS (cast(`created` as date)) NOT NULL, -- <-- generated date column
PRIMARY KEY (`rowId`),
INDEX (`created`), -- <-- datetime index w/ cardinality ~ 1M
INDEX (`created_date`) -- <-- date index w/ cardinality of 1250
INDEX `created_cast` ((cast(`created` as date))) -- <-- functional "date" index w/ cardinality of 1250
-- ^ I WANT TO USE THIS INDEX, BUT DON'T KNOW HOW
) ENGINE=InnoDB;
然后让我们只过滤 2018 年的行,假设:
SELECT COUNT(*) FROM data
WHERE created >= CAST('2018-01-01' AS DATE) AND created < CAST('2019-01-01' AS DATE);
-- Query time: 0.16 s
-- EXPLAIN shows: key: created, Using where; Using index
-- Uses the whole datetime index w/ cardinality of ~ 1M
SELECT COUNT(*) FROM data
WHERE created_date BETWEEN CAST('2018-01-01' AS DATE) AND CAST('2018-12-31' AS DATE);
-- Query time: 0.09 s
-- EXPLAIN shows: key: created_date, Using where; Using index
-- Uses the date index w/ cardinality of 1250
SELECT COUNT(*) FROM data
WHERE CAST(created AS DATE) BETWEEN CAST('2018-01-01' AS DATE) AND CAST('2018-12-31' AS DATE);
-- Query time: 0.35 s, that's slow!
-- EXPLAIN shows: key: NULL, Using where
-- Doesn't use any index at all!
有没有办法使用这个功能索引?
上面的查询使用created
(datetime) 或created_date
(date from generated column) 索引。
有没有办法直接使用功能索引 created_cast
?我什至尝试过USE INDEX
or FORCE INDEX
,但没有运气。
谢谢你们 :)