MySQL按优化排序

yqkkidmi  于 2023-05-16  发布在  Mysql
关注(0)|答案(3)|浏览(125)

下面是表格的结构:
文章: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,但它仍然选择一个索引。有人能解释一下原因吗?

  • 还有关于在此表上添加索引的任何提示,因为添加新索引需要花费大量时间。任何解决方法或在这方面的帮助将不胜感激。*
pu3pd22g

pu3pd22g1#

首先,实时运行整个查询,看看它的性能如何。当您完成一些基准测试后,将查询插入MySQL控制台,并将EXPLAIN前置到它。MySQL不会执行查询,但它会显示它执行查询的计划,包括它认为需要优化的地方,它将使用哪些索引,它必须遍历多少行,以及它将如何有效地遍历每组行,以及其他内容。衡量性能问题的最佳方法是通过基准测试。经常使用它。

rpppsulh

rpppsulh2#

实际上,即使在这里ORDER By ViewsCount, PublishedDateTime也不会使用索引,因为您选择了所有列,并且没有应用任何条件。这是一个真实的的查询吗?因为任何条件都会破坏您的优化。
如果你的表太小了以至于你要把它作为一个整体拉出来,索引只会减慢你的查询速度。(与原始查询相关:SELECT * FROM article ORDER BY ViewsCount DESC, PublishedDateTime;

UPD

如果你有500K+行,我认为你将使用LIMIT子句。我会这样做:
1.在(ViewCount,PublishedDateTime)上添加索引
1.按如下方式重写查询:

SELECT Title
FROM (
    SELECT id
    FROM article
    ORDER BY ViewsCount DESC, PublishedDateTime
    LIMIT 100, 100
) ids
JOIN article
USING (id);

排序将受益于对来自覆盖索引的数据的子集进行操作。join只会通过id获取title。

更新2

当ViewCount的基数相当小时,另一个查询可能会更好地工作(尽管你应该基准测试):

SELECT Title
FROM (
  SELECT ViewCount
  FROM article
  GROUP BY ViewCount DESC) as groups
JOIN article USING (ViewCount)
LIMIT 0, 100;

它还假设您在表上有(ViewCount,PublishedDateTime)索引。

a5g8bdjr

a5g8bdjr3#

ORDER By ViewsCount DESC, PublishedDateTime ASC

MySQL 8.0可以有效地处理 * 如果 * 您有

INDEX(ViewsCount DESC, PublishedDateTime ASC)

8.0 MySQL开始在INDEX规范中使用ASC/DESC。

相关问题