你应该:
上述两点,但是,尤其是关于EXISTS 的那一点会提高你的性能,因为它允许你的查询以惰性求值运行。即,一旦我们检测到第一个真假证据,我们就提前退出而无需完成评估。当您使用 IN 时,您会强制它对该子表达式进行全面评估。
在下文中,我将您的NOT IN 改写为NOT EXISTS。
因为要搜索,所以想在NOT EXISTS做,我创建了对应的索引,保证搜索高效完成。
-- Data
Create Table myTable (UniqReverseID INT, UniqID INT, Month INT);
Insert Into myTable VALUES (6, 2, 9);
Insert Into myTable VALUES (-1, 3, 9);
Insert Into myTable VALUES (9, 4, 9);
Insert Into myTable VALUES (-1, 5, 9);
Insert Into myTable VALUES (2, 6, 9);
-- Indexes
Create Index IX_myTable_001 On myTable (Month, UniqID);
-- Query
Select *
From myTable T1
Where T1.Month = 9
And Not Exists (
Select 1
From myTable T2
Where T2.Month = T1.Month
And T2.UniqID = T1.UniqReverseID
);
我在 SQLite 中运行了上述内容。 SQLite(像许多其他数据库一样)有一个EXPLAIN QUERY PLAN,对于上面它说它使用了两次索引。一次用于 T1 搜索,再次用于 T2 搜索:
SEARCH TABLE myTable AS T1 USING INDEX IX_myTable_001 (Month=?)
CORRELATED SCALAR SUBQUERY 1
SEARCH TABLE myTable AS T2 USING COVERING INDEX IX_myTable_001 (Month=? AND UniqID=?)