如何仅对过滤后的结果集而不是整个表进行排序

时间:2019-10-12 22:50:08

标签: mysql performance sorting

我在这里读到某个地方,ORDER BY仅在存在WHERE子句时才对过滤后的集合进行排序。我看到了一些不同的结果。

我的表有约55万条记录,以下查询在约2.5秒内完成:

SELECT
    *
FROM
    scrapings
WHERE MATCH (title, descr) AGAINST ("young" IN BOOLEAN MODE)
ORDER BY
    dt DESC
LIMIT 100

通过删除ORDER BY子句,时间可以减少到〜0.1秒。如何使它仅对过滤后的结果排序?

哦,我还尝试删除WHERE子句,以确保实际上不需要花费大约2.5秒的时间对过滤的结果进行排序。

哦2:EXPLAIN版本在这里: enter image description here

哦3:这是DDL

CREATE TABLE `scrapings` (
  `url` varchar(512) NOT NULL,
  `dt` int(11) NOT NULL,
  `title` text CHARACTER SET utf8mb4,
  `descr` text CHARACTER SET utf8mb4,
  `image` varchar(1024) DEFAULT NULL,
  `domain` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`url`,`dt`),
  UNIQUE KEY `image` (`image`),
  FULLTEXT KEY `title` (`title`,`descr`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

2 个答案:

答案 0 :(得分:0)

mysql仅对选定的行进行排序。

如果您想知道为什么排序所花的时间如此之久,尤其是当该列没有索引时(所以Daniels的建议很有意义),这是因为mysql创建了一个临时的结果表并对它们进行排序。

如果有人对内部工作方式感兴趣,请阅读了解MySQL内部知识:发现和改进一个很棒的数据库

但是,当涉及where子句时,您在哪里听说过mysql或对mysql进行排序,仅对过滤后的集合进行排序。

答案 1 :(得分:0)

执行查询的唯一方法是:

  1. 使用WHERE
  2. 进行过滤
  3. ORDER BY对整个过滤后的集合进行排序(此处没有索引有用)。请注意,它必须进入记录才能找到dt,以便进行排序。
  4. 发送前100个(LIMIT个)

如果删除WHERE,则它将对整个表进行排序,或者(如果您有INDEX(dt),则可能使用索引来避免排序。

如果仅删除ORDER BY并匹配许多行,则它将仅提供首先找到的100行。这可能会更快。