如何解决MySql使用索引
我有一张这样的桌子:
╔════╦══════════════╦═══════════╗
║ id ║ product ║ date ║
╠════╬══════════════╬═══════════╣
║ 1 ║ P1 ║ 2020-08-01║
║ 2 ║ P2 ║ 2020-08-01║
║ 3 ║ P2 ║ 2020-08-03║
║ 4 ║ P3 ║ 2020-08-04║
╚════╩══════════════╩═══════════╝
目标是查询每天售出多少产品,因此查询是:
SELECT `date`,COUNT(id) AS `totalProductsSoldOnDate`
FROM products
GROUP BY `date`
ORDER BY `date` ASC
输出为:
date totalProductsSoldOnDate
2020-08-01 | 2
2020-08-03 | 1
2020-08-04 | 1
好的。现在,假设我们有一个具有几个记录的方案,并且该查询必须每天运行几次,我们现在需要关心性能以便检索结果。尽可能快。
据我所知,在类似文献的情况下,建议将索引放在GROUP BY和ORDER BY所涉及的列上,在这种情况下为 date
这时的问题是:这是正确的解决方案吗?
此外,假设放置索引很好:
- 对于这种情况,哪个是最有效的索引,为什么?
- 更重要的是:索引如何提高性能?即使有索引日期,我也需要扫描表上的所有行,或者我遗漏了一些东西?
解决方法
输入主键(日期,ID)并创建表InnoDB。这仍然需要全表扫描(因为您没有WHERE子句),但至少应该避免文件排序。
如果要比这更快,请创建一个物化视图,其中包含所需的输出,并使用产品表上的触发器使其保持最新。然后,您将可以运行以下内容:
SELECT * FROM mv_name ORDER BY date;
,
使用次要 INDEX(date,id)
比PRIMARY KEY
更快。这是因为必须扫描的BTree较小。
要大大加快任务的执行时间,请总结当晚的每天数据:http://mysql.rjweb.org/doc.php/summarytables
在这种情况下,让我们看看您拥有什么:
WHERE -- not present
GROUP BY -- just date
ORDER BY -- matches the GROUP BY
the whole query mentions only `date` and `id`
让我们尝试建立最佳索引:
- 使用
WHERE
进行交易-无关。 (可以继续) - 添加所有
GROUP BY
列:INDEX(date,...)
(单击确定以继续) - 由于
ORDER BY
匹配,因此无需执行任何操作。 (可以继续) - 考虑制作“覆盖索引”。也就是说,在查询中的任何位置添加所需的所有其余列。 (但不要使索引“太大”。)
INDEX(date,id)
通过“可以继续”,我的意思是没有砖墙挡住我们:
-
WHERE
中的2个范围测试,不可更改的表达式等 -
GROUP BY
列表与WHERE
冲突(此处不是这种情况) -
ORDER BY
缺少ASC和DESC,或者不同意GROUP BY
。
在JOIN
中,在WHERE
(等等)中提到多个表是一堵砖墙。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。