我有一个包含1亿行的表,我发现以下查询(A)耗时。我正在考虑将其更改为(B),是否一样?
此查询(A):
SELECT *
FROM tab1
WHERE code = 1
AND TYPE = 'A'
AND 0 = (SELECT Count(1)
FROM tab1
WHERE code = 1
AND tr_type = 'APPROVE'
AND security = 'Y')
类似于(B)吗?
SELECT *
FROM tab1
WHERE code = 1
AND TYPE = 'A'
AND NOT EXISTS (SELECT 1
FROM tab1
WHERE code = 1
AND tr_type = 'APPROVE'
AND security = 'Y'
AND ROWNUM = 1)
答案 0 :(得分:1)
是相同的查询。
SELECT *
FROM tab1
WHERE code = 1
AND type = 'A'
AND 0 = (SELECT Count(1)
FROM tab1
WHERE code = 1
AND tr_type = 'APPROVE'
AND security = 'Y')
如果要在上述查询中获取内部查询的输出
SELECT Count(1)
FROM tab1
WHERE code = 1
AND tr_type = 'APPROVE'
AND security = 'Y'
我假设,存在code = 1
,TR_TYPE = 'APPROVE'
和security = 'Y'
的记录。因此输出将为1。(假设只存在一个匹配的记录)。
SELECT *
FROM tab1
WHERE code =1
AND type='A'
AND 0=1 (replacing the result)
因此,由于0永远不等于1,因此不会返回任何数据。
SELECT *
FROM tab1
WHERE code = 1
AND type = 'A'
AND NOT EXISTS (SELECT 1
FROM tab1
WHERE code = 1
AND tr_type = 'APPROVE'
AND security = 'Y'
AND rownum = 1)
现在检查上述查询,内部查询返回1,因为其中存在where子句的数据,所以结果为
SELECT *
FROM tab1
WHERE code =1
AND type='A'
AND NOT EXISTS (1)
Exists(If any record found) = true
,在我们的情况下为Exists(1) = true
,因此
Not Exist (1) = false
。因为它有1条记录,所以它表示false,因此它也不会返回数据。
因此,如果您要求两个查询都将返回相同的输出。因此它将返回相同的输出。
答案 1 :(得分:1)
是的,输出将是相同的,因为它只是使用它的可互换方式,但是在时间复杂度方面,第二个输出已被优化。
答案 2 :(得分:1)
是的,它们是相同的,但是我会在不存在的表上显式地使用别名,并在要比较的列上使用别名。例如:
SELECT *
FROM tab1
WHERE code = 1
AND type = 'A'
AND NOT EXISTS (SELECT 1
FROM tab1 b
WHERE b.code = 1
AND b.tr_type = 'APPROVE'
AND b.security = 'Y'
AND rownum = 1)
答案 3 :(得分:1)
我建议将查询编写为:
SELECT t1.*
FROM tab1 t1
WHERE t1.code = 1 AND
t1.TYPE = 'A' AND
NOT EXISTS (SELECT 1
FROM tab1 tt1
WHERE tt1.code = t1.code AND
tt1.tr_type = 'APPROVE'
tt1.security = 'Y'
);
更改为:
rownum = 1
条件已删除。后者介于冗余和危险之间。 EXISTS
/ NOT EXISTS
已经在寻找任何匹配的行。包含rownum
可以会影响优化程序。
您的第一个版本必须找到 all 个匹配项以计算计数。这比确定没有匹配项或找到第一个匹配项要昂贵得多。
为了提高性能,您希望在tab1(code, tr_type, security)
和tab1(code, type)
上建立索引。