SQL WHERE IN(ID1,ID2,ID3)vs WHERE UNIQUE_ID = IDX

时间:2019-01-15 06:19:54

标签: mysql query-optimization

我用一些伪数据创建了一个表。表( ARTICLES )由ID,author_id,标题,描述组成,表( AUTHOR )由author_id,名称,article_list组成。

首先按照申请流程,我将取出作者列表,这将为我提供作者姓名,文章列表和ID。当用户在作者内部导航时,我可以通过两种方式获取所有文章的列表。

第一

SELECT * FROM  articles WHERE  author_id = 100;

其次,如果我将所有文章的所有列表都以列表的形式保存在作者表中,那么我可以使用

SELECT * 
  FROM  articles 
 WHERE id IN (100, 1100, 2100, 3100, 4100, 5100, 6100, 
            7100, 8100, 9100, 10100, 11100, 12100, 13100, 
            14100, 15100, 16100, 17100, 18100, 19100, 20100,
            21100, 22100, 23100, 24100, 25100, 26100, 27100,
            28100, 29100, 30100, 31100, 32100, 33100, 34100);

第一个查询耗时0.0329秒,第二个查询耗时0.0017秒。

我无法理解第一个查询比第二个查询花费更多的时间。

我所知道的第二个查询将像

那样执行
SELECT * 
  FROM articles 
 WHERE id = 100 
    OR id = 1100 
    OR id = 2100... and so on

2 个答案:

答案 0 :(得分:0)

缓存。

如果启动服务器,然后运行查询,则buffer_pool(或表缓存或...)中什么都没有。因此,需要打开几个文件,需要读取几个块。 32.9毫秒可能表明您需要以大约10毫秒的速度敲击磁盘(如果是HDD)3次。

如果第二次运行相同的查询,所有内容都将被缓存,并且只需要几毫秒,通常不到10毫秒。

由于第一个查询向缓存中填充了一些内容,因此第二个查询找到了它可能需要的大部分(也许全部)块。因此,可能只有CPU,没有I / O。 1.7ms是合理的。

可能的问题...您是否已打开“查询缓存”?如果是这样,那么(在某些情况下)任何SELECT后续执行都将在QC中找到结果集并非常快地返回,可能<1ms。确保避免进行质量控制的一种方法(针对实际时间)是进行SELECT SQL_NO_CACHE ...

您提出的OR查询已优化为您提出的IN。也就是说,它们最终是相同的。 (将OR与不同的列一起使用会导致性能下降;这不是这种情况。)

定时提示:

  • 使用SELECT SQL_NO_CACHE ...(避免进行质量检查)
  • 运行查询两次,并使用 second 计时。 (这避免了其他缓存问题。)

现在要分析如果在author_id上没有 没有任何索引,会发生什么情况。

  • 两个查询将扫描整个表。
  • 显然,这是一个相对较小的表,因为您可以在32.9毫秒内全部读取。
  • 32.9和1.7之间的差异只是缓存。 (我有一条经验法则,即两者之比为10。对于该指标,32.9 / 1.7足够接近我的RoT来支持它。)

如果您有INDEX(author_id),则两个查询可能会运行得更快,无论是否缓存。

答案 1 :(得分:-1)

这可能是因为可能有成千上万的author_id,并且用于:

 SELECT * FROM  articles WHERE  author_id = 100;

每行都需要遍历,因为它应用于整个列行

对于:

 SELECT * FROM  articles WHERE id IN (100, 1100, 2100, 3100, 4100, 5100, 6100, 7100, 8100, 9100, 10100, 11100, 12100, 13100, 14100, 15100, 16100, 17100, 18100, 19100, 20100, 21100, 22100, 23100, 24100, 25100, 26100, 27100, 28100, 29100, 30100, 31100, 32100, 33100, 34100);

它们是有限的记录,对id的一次检查可以通过使用内存来加快遍历速度。