简体   繁体   English

重写SQL查询以优化性能

[英]Rewrite SQL query to optimize performance

I have a query which takes around 2 seconds to load: 我有一个查询,大约需要2秒钟才能加载:

SELECT OUTPUT_VAL.NEXTVAL VAR1_R_ID,A.R_ID,A.VAR1,A.SEQU,A.OUTPUT,B.VAR1 DATATYPE_VAR1 
FROM
( 
    SELECT A.R_ID,A.VAR1,A.SEQU,A.OUTPUT,B.D_TYPE
    FROM
    (
        select A.R_ID, 2484 VAR1,1 SEQU, A.USER OUTPUT 
        from R_TB_1 A 
        WHERE A.R_ID BETWEEN 2457854437 AND 2458854437
        union all
        select A.R_ID, A.MEM_VAR1 VAR1,1 SEQU, MEM_OUTPUT OUTPUT 
        from R_TB_1 A 
        WHERE A.R_ID BETWEEN 2457854437 AND 2458854437
    ) A 
    LEFT JOIN VAR1_TABLE B 
        ON A.VAR1=B.VAR1
) A 
LEFT JOIN VAR1_TABLE B 
    ON A.D_TYPE=B.VAR1_NAME;

How can I rewrite it to improve performance? 如何重写它以提高性能?

So, you have a table VAR1_TABLE with at least three columns, VAR1 , D_TYPE and VAR1_NAME ... you select rows that have a VAR1 column from another table, then you join with VAR1_TABLE on MEM_VAR1 = VAR1 , and then you join again on D_TYPE = VAR1_NAME ? 所以,你有一个表VAR1_TABLE至少有三列, VAR1D_TYPEVAR1_NAME ...你选择有行VAR1从另一个表列,那么你加入VAR1_TABLEMEM_VAR1 = VAR1 ,然后你再加入D_TYPE = VAR1_NAME Can you explain this part, since it makes no sense to me... why are you comparing D_TYPE to VAR1_NAME ? 您能解释一下这部分吗,因为这对我来说毫无意义...为什么将D_TYPEVAR1_NAME进行比较? Just because you can do it and the query runs without errors doesn't mean it makes sense. 仅仅因为您可以做到并且查询运行没有错误并不意味着就可以了。

Assuming the table R_TB_1 has many rows (you seem to be selecting 100,000 rows which is a small portion of the whole table), the UNION ALL means the table is scanned twice. 假设表R_TB_1有很多行(您似乎选择了100,000行,这是整个表的一小部分),那么UNION ALL表示该表被扫描了两次。 You may be better off selecting just once, in a CTE, and then doing the union based on the CTE... if your version is at least Oracle 11.1. 如果您的版本至少是Oracle 11.1,则最好只在CTE中选择一次,然后再基于CTE进行合并...。 (By the way, state your Oracle version whenever you ask a question!) If you are on Oracle 10 or below, you will need subqueries like you have now. (顺便说一句,每当您提出问题时,请声明您的Oracle版本!)如果您使用的是Oracle 10或更低版本,则将需要像现在一样的子查询。

Something like this: 像这样:

with 
     Z ( R_ID, MEM_VAR1, USER, MEM_OUTPUT ) as (
       select R_ID, MEM_VAR1, USER, MEM_OUTPUT
       from   R_TB_1
       where  R_ID between 2457854437 and 2458854437
     ),
     A ( R_ID, VAR1, SEQU, OUTPUT ) as (
       select R_ID, 2484    , 1, USER
         from Z
       union all
       select R_ID, MEM_VAR1, 1, MEM_OUTPUT
         from Z 
     )
select  -- your joins from A to the other table here; A is defined in the WITH clause
WITH temp AS (
SELECT OUTPUT_VAL.NEXTVAL VAR1_R_ID,A.R_ID,A.VAR1,A.SEQU,A.OUTPUT,B.VAR1 DATATYPE_VAR1 FROM

( 
SELECT A.R_ID,A.VAR1,A.SEQU,A.OUTPUT,B.D_TYPE FROM
(
SELECT A.R_ID, 2484 VAR1,1 SEQU, A.USER OUTPUT from R_TB_1 A WHERE A.R_ID BETWEEN 2457854437 AND 2458854437

union ALL

select A.R_ID, A.MEM_VAR1 VAR1,1 SEQU, MEM_OUTPUT OUTPUT from R_TB_1 A WHERE A.R_ID BETWEEN 2457854437 AND 2458854437
)
A LEFT JOIN VAR1_TABLE B ON A.VAR1=B.VAR1 ) 
A LEFT JOIN VAR1_TABLE B ON A.D_TYPE=B.VAR1_NAME
)
SELECT * FROM temp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM