我有一个非常慢的查询,看起来像这样:
SELECT *
FROM (
SELECT ..., nn_key_fast(nachname) nnk, ...
FROM t1
JOIN t2 ON
...
JOIN t3 ON
...
JOIN t4 ON
...
WHERE ...
AND t4.POSTCODE='1234'
)
WHERE ... AND nnk LIKE "N%"
现在,内部选择大约需要2分钟。如果删除最后一个WHERE子句(t4.POSTCODE),它将在约4秒内执行。没有此子句的结果将是<1000条记录,因此是一个很小的集合。
因此,我的想法是:将该子句移至外部SELECT,然后将其仅应用于所得的<1000条记录。
但是没有。该查询花费的时间正好长,因此要明确:
SELECT *
FROM (
SELECT .....
FROM t1
JOIN t2 ON
...
JOIN t3 ON
...
JOIN t4 ON
...
WHERE ...
)
WHERE ...
AND POSTCODE='1234'
与第一个版本花费2分钟相同的时间。
这对我来说似乎很疯狂。
直观上讲,这必须由查询优化器执行,如下所示: 从内部选择中创建一个表,如下所示:
CREATE TABLE res_from_inner AS (
SELECT .....
FROM t1
JOIN t2 ON
...
JOIN t3 ON
...
JOIN t4 ON
...
WHERE ...
)
...,然后仅在此表上进行外部选择,如下所示:
SELECT *
FROM res_from_inner
WHERE POSTCODE='1234'
如果我手动执行此操作,则CREATE TABLE查询大约需要4秒钟,而第二个SELECT则需要1秒钟。
这怎么可能,怎么办?
答案 0 :(得分:1)
您必须查看执行计划以了解实际情况。情况正在改变。
您可以尝试的一件事是CTE:
with s as (
<subquery here>
)
select s.*
from s
where . . .;
Oracle可能会自动实现。或者您可以给出提示:
with s as (
select /*+ materialize */ . . .
. . .
)
select s.*
from s
where . . .;
答案 1 :(得分:1)
我尝试远离嵌套的select语句。在这种情况下,我会将内部的select语句作为子查询,然后从中选择想要的内容。
,子查询为( 从...中选择...加入...加入...加入... )
从子查询中选择*
-希望有帮助:]