Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
重写SQL查询以优化性能_Sql_Oracle - Fatal编程技术网

重写SQL查询以优化性能

重写SQL查询以优化性能,sql,oracle,Sql,Oracle,我有一个大约需要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

我有一个大约需要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;
如何重写它以提高性能?

因此,您有一个至少包含三列的表VAR1\u table,VAR1、D\u TYPE和VAR1\u NAME。。。从另一个表中选择具有VAR1列的行,然后在MEM_VAR1=VAR1上与VAR1_表联接,然后在D_TYPE=VAR1_NAME上再次联接?你能解释一下这一部分吗,因为它对我来说毫无意义。。。为什么要将D_类型与VAR1_名称进行比较?仅仅因为您可以这样做,并且查询运行时没有错误,并不意味着这是有意义的

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
假设表R_TB_1有许多行,您似乎选择了100000行,这是整个表的一小部分,那么UNION意味着该表将被扫描两次。你最好在CTE中只选择一次,然后根据CTE进行联合。。。如果您的版本至少是Oracle 11.1。顺便说一下,无论何时提出问题,请说明您的Oracle版本!如果您使用的是Oracle 10或更低版本,您将需要像现在这样的子查询

大概是这样的:

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

如果可能的话,添加表结构以便我们能够更好地理解问题。首先,重写它以提高可读性。然后,它取决于我们不知道的一千个因素,因此用户:表、记录数、现有索引和触发器等,因此,在这里很难真正帮助您。请您的问题为相关表添加CREATETABLE语句,包括所有索引和查询的执行计划。请发短信,当你给出答案时,你能提供更多关于原因的细节吗?同时用4倍空格缩进代码,使其出现在语法颜色的代码块中。您能解释一下您的代码和原始代码之间有什么改进吗?似乎您只将原始SQL放在CTE中,这不会提高性能