如何优化此嵌套SQL SELECT查询

问题描述 投票:0回答:2

我有一个非常慢的查询,如下所示:

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),它将在~4secs中执行。没有这个子句的结果将是<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秒。

这怎么可能,怎么做呢?

sql oracle subquery oracle10g query-optimization
2个回答
1
投票

你必须查看执行计划才能看到真正发生的事情。事情正在发生变化。

您可能尝试的一件事是CTE:

with s as (
      <subquery here>
     )
select s.*
from s
where . . .;

Oracle可能会自动实现这一点。或者你可以给一个提示:

with s as (
      select /*+ materialize */ . . .
      . . .
     )
select s.*
from s
where . . .;

1
投票

我试图远离嵌套的select语句。在这种情况下,我将内部select语句作为子查询,然后从中选择我想要的。

子查询为(select ... from ... join ... join ... join ... where)

从子查询中选择*

- 希望有助于:]

© www.soinside.com 2019 - 2024. All rights reserved.