我用一些伪数据创建了一个表。表( 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
答案 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 ...
(避免进行质量检查)现在要分析如果在author_id
上没有 没有任何索引,会发生什么情况。
如果您有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的一次检查可以通过使用内存来加快遍历速度。