2011-03-16 28 views
3

下面的查询需要太多的时间,最有可能的。SQL查询“不”条款的执行“不中”的使用需要,因为太长

你可以提出任何改进的地方?

SELECT vcode, 
     vname, 
     1014 AS fid 
FROM testcodes co 
WHERE co.vcode NOT IN (SELECT dict.vcode 
         FROM datadictionary dict 
         WHERE dict.fid = 1014) 

有关结构的一点是。 vCode,vName是varchar 和testCodes和DataDictionary具有相同的结构。

我搜索这个问题,发现左连接都不可能解决这个问题? (为什么它做得更好,如何做到)?

可有人引导,如果它能够提高???

回答

7
SELECT vcode, 
     vname, 
     1014 AS fid 
FROM testcodes co 
     LEFT JOIN datadictionary dict 
     ON co.vcode = dict.vcode 
      AND dict.fid = 1014 
WHERE dict.vcode IS NULL 

您必须对创建索引:

  • (testcodes.vcode)
  • (datadictionary.vcode,datadictionary.fid)

两个做一个索引扫描在每个表上,但IN有一个合并连接,并且INNER JOIN有一个哈希匹配。

+4

至于为什么它的速度更快:在'LEFT JOIN'语法告诉查询优化器如何联接表的更直接的方式,而'NOT IN(SELECT ...)'是更灵活,但需要从更多的工作数据库引擎。 – geekosaur 2011-03-16 07:30:02

+0

即使没有索引。查询运行DAMN FAST。我写的查询花了一分多钟甚至仅仅几千条记录(在数据字典中几乎10K,在测试代码中3K) – Umer 2011-03-16 07:39:58

+0

顺便说一句,感谢这样的编辑,我总是会混淆如何缩进那些sql脚本:) – Umer 2011-03-16 07:41:19

0

该查询看起来没问题。 尝试添加以下指标

数据字典指数(FID,VCODE)
testCodes指数(VCODE)

+0

查询不正常,因为它不以优化的方式使用索引。 – Pentium10 2011-03-16 07:31:24

+0

不知道我是否同意,使用我列出的索引的原始查询将在datadictionary和测试代码上执行索引查找,这意味着数据库引擎永远不会触及不需要的记录。您将对两个表格进行全索引扫描,触及每个索引中的每个条目。对我来说,更少的磁盘活动几乎总是更快。我感兴趣的是哪个更快:) – 2011-03-16 07:50:24

+0

这取决于数据库引擎MSSQL,MySQL,SQLite或Postgres。无论如何,使用连接在每个平台上比子选择更快。 – Pentium10 2011-03-16 07:55:44

1

如果dict.fid是一个独特的密钥(听起来是如此),那么你的查询应相当于

WHERE co.vcode != (SELECT dict.vcode -- ... 

co.vcode和dict.vcode可能需要一个索引来加快速度。

这个答案不试图给出比Pentium10更好的提示,更多的是阿里纳斯。