首页 > 解决方案 > 对大量记录有更好的查询性能

问题描述

我有一个表叫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我得到

在此处输入图像描述

另外,我尝试添加Indexdhikr_library_id但我得到了相同的运行时。

标签: mysqlsql

解决方案


我希望您的索引会略微减少 I/O,因为要细读的原始数据较少,但显然可以忽略不计,无论如何它都必须回到主表中deleted_at。您可以尝试添加deleted_at到该索引。也许查看查询计划会提供线索,但您可能只是磁盘速度较慢。如果 MySQL 有一个奇怪的低效率,你可以尝试count(*),但我不希望这会取得很大的成就。


推荐阅读