我写了下面的查询,里面有很多' AND'运营商,我想知道如何优化以下查询的性能[我可以删除一些' AND'算]
SELECT I.date,
K.somcolumn,
L.somcolumn,
D.somcolumn
FROM Table1 I,
Table2 K,
Table3 L,
Table4 D
WHERE I._ID = K._ID
AND K.ID = L._ID
AND L._ID = I._ID
AND I._CODE = L._CODE
AND K.ID = D._ID(+)
AND L._ID IN ( SELECT _id
FROM I
WHERE UPPER (someflag) = 'TRUE'
GROUP BY _id
HAVING COUNT (*) > 1)
AND L._ID IN ( SELECT _id
FROM I
WHERE UPPER (code) = 'OPEN'
GROUP BY _id
HAVING COUNT (*) > 1)
ORDER BY I._ID, I._CODE;
答案 0 :(得分:2)
根据我的判断,您无法合并任何条件,但您可以使用标准AND
语法改进查询并减少JOIN
运算符的数量:
SELECT I.date,
K.somcolumn,
L.somcolumn,
D.somcolumn
FROM Table1 I
INNER JOIN Table2 K ON I._ID = K._ID
INNER JOIN Table3 L ON K.ID = L._ID
LEFT JOIN Table4 D ON K.ID = D._ID
WHERE L._ID IN ( SELECT _id
FROM I
WHERE UPPER (someflag) = 'TRUE'
GROUP BY _id
HAVING COUNT (*) > 1)
AND L._ID IN ( SELECT _id
FROM I
WHERE UPPER (code) = 'OPEN'
GROUP BY _id
HAVING COUNT (*) > 1)
ORDER BY I._ID, I._CODE;
以此为基础,如果您加入子查询条件而不是使用相关子查询,可能会获得优化提升。没有保证,但这样的事情可能会有所帮助:
SELECT I.date,
K.somcolumn,
L.somcolumn,
D.somcolumn
FROM Table1 I
INNER JOIN Table2 K ON I._ID = K._ID
INNER JOIN Table3 L ON K.ID = L._ID
LEFT JOIN Table4 D ON K.ID = D._ID
INNER JOIN (
SELECT _id
FROM I
WHERE UPPER (someflag) = 'TRUE'
GROUP BY _id
HAVING COUNT (*) > 1
) someflagtrue ON L._ID = someflagtrue._id
INNER JOIN (
SELECT _id
FROM I
WHERE UPPER (code) = 'OPEN'
GROUP BY _id
HAVING COUNT (*) > 1
) codeopen ON L._ID = codeopen._id
ORDER BY I._ID, I._CODE;
答案 1 :(得分:0)
您可以将两个子查询替换为一个。
旧子查询:
SELECT _id
FROM I
WHERE UPPER (someflag) = 'TRUE'
GROUP BY _id
HAVING COUNT (*) > 1)
SELECT _id
FROM I
WHERE UPPER (code) = 'OPEN'
GROUP BY _id
HAVING COUNT (*) > 1)
新子查询:
SELECT _ID
FROM I
GROUP BY _ID
HAVING COUNT(CASE WHEN UPPER(SOMEFLAG) = 'TRUE' THEN 1 ELSE 0 END) > 0
AND COUNT(CASE WHEN UPPER(CODE) = 'OPEN' THEN 1 ELSE 0 END) > 0
在大多数情况下,这应该至少快一点,因为它可能会减少全表扫描和连接的数量。但是很难说你的系统是否会更快,因为优化器有很多可能的选择。
在清理查询后,性能调整的下一步是生成解释计划。运行explain plan for select ...;
,然后运行select * from table(dbms_xplan.display);
这将显示查询是如何执行的,这可能会提示您什么是缓慢的,哪些可以改进。如果您需要更多帮助,请将解释计划的完整输出添加到您的问题中。它还可以帮助添加有关相关表中的行数,返回的行数以及索引的信息。