选择查询检查的行数多于表中现有的行数

Has*_*bur 5 mysql sql database

数据库内容只有 9100 篇文章但是同时命中了这个查询

SELECT * 
FROM `ABC` 
WHERE st=6 AND publish_on <= '2018-02-01' 
ORDER BY rand() LIMIT 5
Run Code Online (Sandbox Code Playgroud)

查询时间:1.043072 锁定时间:0.000081 已发送行数:5 已检查行数:19354

但 :

Select count(*) from ABC;
Run Code Online (Sandbox Code Playgroud)

它返回:

9100
Run Code Online (Sandbox Code Playgroud)

为什么它检查 19354 行?

小智 2

您可以在此链接中查看函数的工作原理rand()

在此链接上,您可以看到如何ORDER BY工作:

  1. 像以前一样读取与 WHERE 子句匹配的行。
  2. 对于每一行,记录一个由排序键值和行位置组成的值元组,以及查询所需的列。
  3. 按排序键值对元组进行排序
  4. 按排序顺序检索行,但直接从排序的元组中读取所需的列,而不是再次访问表。

我认为您的查询检查了 19354 行(比表行总数还多),因为使用order by rand(), rand() 的组合不是表的列(因此没有排序键),因此 dbms 必须扫描表超过 1 次。如果您按表的列排序,我不确定,但 dbms 可能不需要只扫描表一次。

此外,执行 a 的ORDER BY rand() LIMIT 5效率非常低,因为您之前对 9100 行进行了排序,而只选择了 5 行。