以下是示例的简化表:
这是我的疑问:
SELECT * FROM article A
在哪里A.id IN(
从文章A1,article_tag AT
中选择AT.article_idWHERE(A1.id = AT.article_id)
AND(AT.tag_id IN (2,1))
GROUP BY AT.article_id
有计数(AT.article_id)= 2
);
从技术上讲,此查询似乎有效并返回 "all the articles having at least keywords 2 and 1"
。
大胆的部分是要改变的。例如,如果我的关键字列表是[1,3,4],
(2, 1)
将更改为(1,3,4),2
将更改为 3 (列表的长度)。
虽然这个查询确实有用,但我稍微记得一个朋友使用 NOT EXISTS 子句。适用吗?如果是,哪个查询是性能方面的最佳优化?
答案 0 :(得分:2)
您不需要EXISTS或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;
答案 1 :(得分:1)
如果是,哪个查询在性能方面是最佳优化?
优化sql时,您唯一的朋友是查询计划并打开统计信息。结果通常取决于表中的数据。在查询计划中,您可以看到sql-server在某些表上执行的操作,使用统计信息可以查看原始计时和读取。
查看查询时,您可以创建内部联接,EXISTS,IN,表值函数,内联表值函数等。在许多情况下,sql server会将它们优化为相同的查询计划。但是在某些情况下它没有。首先进行查询并查看需要哪些索引,在许多情况下,索引比编写查询的方式更重要。
优化SQL查询的关键是使用实际数据和实际参数。然后测量,测量,测量和分析IO /读数/计时等。
答案 2 :(得分:0)
我可以看到的一个问题是数据库无法重用查询计划,因为对于不同的参数,您正在更改查询文本。这通常会导致次优的查询计划。
因此,不要考虑in
与exists
,而应考虑将选项作为参数传递。您没有指定您正在使用的数据库引擎,所以我不能说具体的内容。例如,在MS SQL上,您可以使用表参数或xml
参数来执行此操作,从而帮助查询计划程序完成其工作。
还可以使用一些技巧来使查询更直接,但这只是关于如何使用查询以及如何执行查询的具体统计信息。
警惕轶事证据 - 很多反对使用in (subquery)
和类似论点的论点已有数年之久,不再需要适用于您的场景。测量。准备真实的测试数据。测量。猜测伤害:)