【问题标题】:SQL Server speed up query with not inSQL Server 使用 not in 加速查询
【发布时间】:2012-05-08 03:21:24
【问题描述】:

我有一个名为 sales 的表,其中包含以下几列:

salesno (PK, char(25))
advanceno (char(15), not null)

现在我想选择salesno 不在advanceno 中的所有行:

SELECT salesno 
FROM sales 
WHERE salesno NOT IN (SELECT advanceno FROM sales)

查询很慢,因为sales表有几十万行。

我这样做了,而且速度非常快:

SELECT salesno 
FROM sales 
WHERE salesno NOT IN ('000008360', '000008361', '000008362', '000008363', '000008364')

如何优化查询?

【问题讨论】:

  • 连接通常比 where 限制快。
  • sales表上是否有索引?
  • 最后一次更新统计数据是什么时候?有一段时间了吗?自那以后是否添加了相当多的行数?
  • 无索引,只有salesno为主键。
  • xQbert,这是事实还是您的意见?无论如何都会有加入。优化器选择的连接算法是有问题的。许多人会说 NOT EXISTS,或者,如果没有 NULLS,NOT IN 将是最好的选择。通常,LEFT JOIN 将是一个完整的连接,返回所有匹配的行(包括重复行),然后进行过滤。 NOT EXISTS 或 NOT IN 更可能是反半连接(部分连接),不连接所有行,而只是检查不存在。 sqlinthewild.co.za/index.php/2010/03/23/…

标签: sql-server sql-server-2008r2-express


【解决方案1】:

试试这个:

DECLARE @sales as Table (salesno char(25)
,advanceno char(15) not null)

INSERT INTO @sales(salesno,advanceno)
SELECT '000008360','000008360' UNION ALL
SELECT '000008361','000008362' UNION ALL
SELECT '000008362','000008364' 

SELECT  s.salesno 
FROM    @sales s 
LEFT JOIN @sales a ON a.advanceno = s.salesno
WHERE   a.advanceno IS NULL

在你的例子中,试试这个

SELECT  s.salesno 
FROM    sales s 
LEFT JOIN sales a ON a.advanceno = s.salesno
WHERE   a.advanceno IS NULL

【讨论】:

  • 比 not in 方法要慢。
  • 令人惊讶的是,当我索引Advanceno时,它非常快。
  • @Lelvin:这一点也不令人惊讶!
  • @marc_s 至少我很惊讶。我很乐观!
猜你喜欢
  • 2012-08-18
  • 1970-01-01
  • 2015-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
  • 1970-01-01
相关资源
最近更新 更多