看到NOT IN和NOT EXISTS之间的一些主要性能差异,有没有更好的选择“列NOT IN(1,2,3)”?
想知道,出于兴趣,是否可以优化此查询?
-- (ignore the SELECT *)
SELECT *
FROM `comments`
WHERE comment_id NOT IN (65,64,63)
ORDER BY `comment_id` DESC
看到NOT IN和NOT EXISTS之间的一些主要性能差异,有没有更好的选择“列NOT IN(1,2,3)”?
想知道,出于兴趣,是否可以优化此查询?
-- (ignore the SELECT *)
SELECT *
FROM `comments`
WHERE comment_id NOT IN (65,64,63)
ORDER BY `comment_id` DESC
假设comment_id
是表comments
的主键,我不认为这可以改进。我不明白你为什么想尝试。您的条件位于主键上,因此查询应使用索引。
MySQL将其所有数据放在主键“后面”。或者,如the documentation所示:
每个InnoDB表都有一个特殊索引,称为聚集索引,其中存储行的数据。通常,聚集索引与主键是同义的。
(...)
- 如果不定义你的表的主键,MySQL的定位,所有的键列NOT NULL第一UNIQUE索引和InnoDB使用它作为聚集索引。
所以,如果您的查询使用的主键,这是最快的方式检索您的数据。
解释计划说什么?
为什么你觉得有必要尝试优化呢?
NOT IN
和NOT EXISTS
之间的性能差异使用子选择“填充” IN列表时,仅仅是。
比较
SELECT c.*
FROM comments c
WHERE c.author_id NOT IN (
SELECT a.author_id
FROM authors a
WHERE a.first_name = 'Jay'
);
与
SELECT c.*
FROM comments c
WHERE NOT EXISTS (
SELECT *
FROM authors a
WHERE c.author_id = a.author_id
AND a.first_name = 'Jay'
);
,但我会用
SELECT c.*
FROM comments c
LEFT JOIN authors a
ON (c.author_id = a.author_id AND a.first_name = 'Jay')
WHERE a.author_id IS NULL;
注意他们的行为,如果有NULL的参与完全不同。 – jarlh