[英]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
至少有三列, VAR1
, D_TYPE
和VAR1_NAME
...你选择有行VAR1
从另一个表列,那么你加入VAR1_TABLE
上MEM_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_TYPE
与VAR1_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.