下面是表格的结构:
文章:ID、标题、描述、发布日期时间、浏览次数、发布时间
主键:ID
使用的查询:
Select Title FROM Article ORDER By ViewsCount DESC, PublishedDateTime ASC
正如您所看到的,我混合使用了ASC和DESC &根据MySQLOrderBy优化,将不使用索引。
我想使用一个复合索引,使用ViewsCount和PublishedDateTime。你建议使用2个不同的键而不是使用复合索引。但后来我读到复合索引比使用2个不同的键更好(如果两个字段都要使用)。
分享更多信息:
该表包含超过550K+记录,我也有很大的麻烦,在添加和删除索引的测试目的。你们有什么推荐的吗我应该在小样本上测试吗?
下面是一些更多的见解:
使用索引:
1)浏览次数
2)发布日期时间。
3)ViewsCount & PublishedDateTime(命名为ViewsDate_Index)
A)EXPLAIN混合ASC和DESC查询:
EXPLAIN SELECT title FROM `article` ORDER BY ViewsCount DESC , PublishedDateTime ASC LIMIT 0 , 20
====+===============+=========+======+===============+=====+=========+======+========+================+
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | article | ALL | NULL | NULL| NULL | NULL | 550116 | Using filesort
====+===============+=========+======+===============+=====+=========+======+========+================+
B)EXPLAIN查询使用相同的排序顺序:
EXPLAIN SELECT title FROM `article` ORDER BY ViewsCount DESC , PublishedDateTime DESC LIMIT 0 , 20
====+===============+=========+=======+===============+=================+=========+=============+========+================+
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | article | index | NULL | ViewsDate_Index | 16 | NULL | 550116 |
====+===============+=========+=======+===============+=================+=========+=============+========+================+
您可以看到,如果ViewsCount和PublishedDateTime的排序顺序相同,则它使用ViewsDate_Index索引。我发现奇怪的一件事是,possible_keys是NULL,但它仍然选择一个索引。有人能解释一下原因吗?
- 还有关于在此表上添加索引的任何提示,因为添加新索引需要花费大量时间。任何解决方法或在这方面的帮助将不胜感激。*
3条答案
按热度按时间pu3pd22g1#
首先,实时运行整个查询,看看它的性能如何。当您完成一些基准测试后,将查询插入MySQL控制台,并将
EXPLAIN
前置到它。MySQL不会执行查询,但它会显示它执行查询的计划,包括它认为需要优化的地方,它将使用哪些索引,它必须遍历多少行,以及它将如何有效地遍历每组行,以及其他内容。衡量性能问题的最佳方法是通过基准测试。经常使用它。rpppsulh2#
实际上,即使在这里
ORDER By ViewsCount, PublishedDateTime
也不会使用索引,因为您选择了所有列,并且没有应用任何条件。这是一个真实的的查询吗?因为任何条件都会破坏您的优化。如果你的表太小了以至于你要把它作为一个整体拉出来,索引只会减慢你的查询速度。(与原始查询相关:
SELECT * FROM article ORDER BY ViewsCount DESC, PublishedDateTime;
)UPD
如果你有500K+行,我认为你将使用
LIMIT
子句。我会这样做:1.在(ViewCount,PublishedDateTime)上添加索引
1.按如下方式重写查询:
排序将受益于对来自覆盖索引的数据的子集进行操作。join只会通过id获取title。
更新2
当ViewCount的基数相当小时,另一个查询可能会更好地工作(尽管你应该基准测试):
它还假设您在表上有(ViewCount,PublishedDateTime)索引。
a5g8bdjr3#
MySQL 8.0可以有效地处理 * 如果 * 您有
8.0 MySQL开始在INDEX规范中使用ASC/DESC。