2015-03-03 15 views
2

下面是该示例的简化表:在VS中NOT EXISTS子句,查询优化

my tables

这是我的查询:

SELECT * FROM A条

在哪里A.id IN(

SELECT AT.article_id从文章A1,article_tag AT

WHERE(A1.id = AT.article_id)

AND(AT.tag_id IN (2,1)

GROUP BY AT.article_id

HAVING计数(AT。 article_id)=

);

技术上该查询似乎工作,返回"all the articles having at least keywords 2 and 1"

大胆的部分是为了改变。举例来说,如果我的关键字列表是[1,3,4],

(2, 1)将变更为(1,3,4)2将变更为(列表的长度)。

虽然这个查询不会工作,我微微记得使用朋友NOT EXISTS条款。它适用吗?如果是,哪个查询在性能方面是最佳优化?

+0

在子查询中统计不同! – jarlh 2015-03-03 08:09:04

+1

EXISTS或多或少与IN相同,至少在(大多数)dbms优化之后。 (NOT EXISTS是NOT IN的一个“无效安全”替代方法。) – jarlh 2015-03-03 08:13:27

+0

您也可以在子查询中的两个条件上应用联接,但是当您查看它时,这同样会变得清晰。 – 2015-03-03 08:15:38

回答

1

如果是,哪个查询在性能方面是最佳优化?

当优化sql你唯一的朋友是查询计划和开启统计。结果通常取决于表格中的数据。在查询计划中,您可以看到sql-server在某些表上以及统计数据上可以看到的原始计时和读数。

查看您的查询时,您可以创建INNER JOIN,EXISTS,IN,TABLE VALUED FUNCTION,INLINE TABLE VALUED FUNCTION等。在许多情况下,sql server会将它们优化为相同的查询计划。但是在某些情况下它不会。首先进行查询并查看需要哪些索引,在许多情况下,索引比编写查询的方式更重要。

优化sql查询的关键是使用真实数据和实参。然后测量,测量,测量和分析IO /读取/计时等。

+0

我很好奇 - 什么告诉你,OP是使用SQL服务器? – 2015-03-03 08:44:53

0

我可以看到的一个问题是数据库将无法重用查询计划,因为对于不同的参数,查询文本。这通常会导致次优查询计划。

因此,不要考虑inexists,请考虑将选项作为参数传递。你没有指定你正在使用的数据库引擎,所以我不能说任何具体的东西。例如,在MS SQL上,可以使用表参数或xml参数来执行此操作,从而帮助查询计划员完成其工作。

还有一些技巧可以用来使查询更直接,但是这种情况你应该只使用关于如何使用查询以及如何执行的具体统计信息。

警惕轶事证据 - 很多反对使用in (subquery)及类似软件的论点已有多年,不再需要适用于您的情况。测量。准备切合实际的测试数据。测量。猜测伤害:)

2

你不需要存在或IN - 只是GROUP BY文章的所有列,你就完成了。示例(在Oracle语法中,因为您没有提到您的RDBMS):

with article(id, title) as (
    select 1, 'MS SQL Server' from dual union all 
    select 2, 'Oracle' from dual union all 
    select 3, 'PostgreSQL' from dual union all 
    select 4, 'IDBM DB2' from dual), 
    article_tag(id, article_id, tag_id) as (
    select 1,1,1 from dual union all 
    select 2,1,2 from dual union all 
    select 3,2,1 from dual union all 
    select 4,3,2 from dual 
) 
    SELECT a.id, a.title 
    FROM article a 
    JOIN article_tag at ON a.id = at.article_id 
     AND at.tag_id IN (2,1) 
    GROUP BY a.id, a.title 
    HAVING COUNT(at.article_id) = 2; 
+0

啊这是正确的.. – user544262772 2015-03-03 09:43:41