mysql - 对大量记录有更好的查询性能
问题描述
我有一个表叫routine_dhikrs
这个表有大概~1,696,695
的记录,表结构如下
CREATE TABLE `routine_dhikrs` (
`id` bigint(20) UNSIGNED NOT NULL,
`dhikr_library_id` bigint(20) UNSIGNED NOT NULL,
`user_routine_id` bigint(20) UNSIGNED NOT NULL,
`goal` int(11) DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
对于外键和索引
我想要做的是获得前十名dhikr_library_id
(我的意思是按该列计数和分组)。所以结果如下。
+------------------+-------+
| dhikr_library_id | count |
+------------------+-------+
| 11 | 36595 |
| 110 | 36538 |
+------------------+-------+
到目前为止我所达到的是
SELECT RD.dhikr_library_id, COUNT(RD.dhikr_library_id) as COUNT
FROM routine_dhikrs AS RD
WHERE RD.deleted_at IS NULL
GROUP BY RD.dhikr_library_id
ORDER BY count DESC
LIMIT 10
这个查询给了我正确的结果,到目前为止我没有问题,对我来说问题是查询需要大约 6.5 秒才能运行,所以有没有更好的方法可以更快地获取这些数据?
当我跑步时,explain
我得到
另外,我尝试添加Index
,dhikr_library_id
但我得到了相同的运行时。
解决方案
我希望您的索引会略微减少 I/O,因为要细读的原始数据较少,但显然可以忽略不计,无论如何它都必须回到主表中deleted_at
。您可以尝试添加deleted_at
到该索引。也许查看查询计划会提供线索,但您可能只是磁盘速度较慢。如果 MySQL 有一个奇怪的低效率,你可以尝试count(*)
,但我不希望这会取得很大的成就。
推荐阅读
- sql - 遇到案件时对 ID 进行排序
- node.js - 为什么除了 passport.js 还要使用 cookie-session?
- primefaces - 如何在 ap:dataTable 中使用“sortBy”和 HashSet 集合
- hololens-emulator - 将文件复制到 HoloLens 模拟器
- flutter - 将 ListView 嵌套到 DropdownMenu
- python - sklearn train_test_split - ValueError:找到样本数量不一致的输入变量
- vue.js - 如何重置组件的状态值?
- javascript - discord.js - 从所有成员中删除特定角色
- gunicorn - FastAPI gunicon uvicorn access_log 格式定制
- php - property_exists() 检查类方法中是否存在静态属性