mysql - 优化二级索引和日期范围查询
问题描述
我正在运行一个聚合查询,它花费的时间比预期的要长得多。查询来自没有连接的单个表。where 子句包括日期范围、in
子句和日期列。表中只有大约 5k 行,查询时间为 13s。
查询是:
select `site_id`, created_year_month_idx as time_column, count(*) as total
from `patients`
where `created_year_month_idx` between 20080101 and 20090101 and
`site_id` in (1,2,3) and
`patients`.`deleted_at` is null
group by `created_year_month_idx`, `site_id`
当我解释查询时,它似乎在进行全表扫描:
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
| --- | ----------- | -------- | ---------- | ----- | --------------------------------------------- | ------------------------------------- | ------- | --- | ---- | -------- | -------------------------------------------- |
| 1 | SIMPLE | patients | | range | site_id,patients_created_year_month_idx_index | patients_created_year_month_idx_index | 4 | | 1 | 100 | Using where; Using temporary; Using filesort |
表创建语句是:
CREATE TABLE `sites` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(10),
PRIMARY KEY (`id`)
);
CREATE TABLE `patients` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`site_id` int(10) unsigned NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`created_year_month_idx` date GENERATED ALWAYS AS (date_format(`created_at`,'%Y-%m-01')) VIRTUAL,
PRIMARY KEY (`id`),
KEY `site_id` (`site_id`),
KEY `patients_created_year_month_idx_index` (`created_year_month_idx`),
CONSTRAINT `patients_site` FOREIGN KEY (`site_id`) REFERENCES `sites` (`id`)
);
我在https://www.db-fiddle.com/f/4zbjFpMYXEGSviprQcaTm3/0创建了一个 DB Fiddle
(顺便说一句,如果你能告诉我如何在 SO 上格式化降价表,我会解决上述问题)
解决方案
我投票给
INDEX(`deleted_at`, `created_year_month_idx`, `site_id`)
但主要是因为它是“覆盖”。 deleted_at
是第一个,因为它本质上是一个相等测试 ( IS NULL
)。
你知道你有一年加一天吗? BETWEEN 20080101 AND 20090101
你真的想要大约 1K 行的输出吗?
推荐阅读
- reporting-services - SSRS 不良结果
- javascript - 无法读取未定义的属性 myFunction
- python - 有没有办法改变普通代码或文本的特定字符的颜色
- apache-kafka - kafka rest api和confulent rest代理之间的区别?
- android - Withings API 断开/撤销令牌
- dask - dask dataframe,to_parquet 首先创建一个 10 kb 文件,然后创建其余文件
- c++ - 如何编写一个将被扩展以定义具有模板参数的对象的宏
- flutter - 颤振错误:元素类型“按钮”不能分配给列表类型“小部件”
- authentication - Cloud Run - 通过服务帐户进行 gRPC 身份验证 - Java
- electron - 有没有办法在 Electron 中将本地文件加载到 HTML 中?获取 ERR_UNKNOWN_URL_SCHEME