【问题标题】:Better query performance for large number of records [duplicate]大量记录的更好查询性能[重复]
【发布时间】:2021-05-13 01:19:53
【问题描述】:

我有一个叫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 时,我得到了

另外,我尝试在 dhikr_library_id 上添加 Index,但运行时相同。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

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

    【讨论】:

    • 问题出现在deleted_at 列中,因为它没有INDEX
    • 具体应该是这个顺序:INDEX(deleted_at, dhikr_library_id)。相反的顺序不太好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多