2016-09-08 3 views
0

У меня есть запрос, который занимает около 2 секунд для загрузки:Переписать SQL запрос для оптимизации производительности

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; 

Как я могу переписать его, чтобы улучшить производительность?

+1

если возможная структура добавить таблицу, чтобы мы могли иметь более глубокое понимание вопроса – techipank

+0

Во-первых, переписать его, чтобы улучшить читаемость. – Rik

+0

Тогда это зависит от тысячи неизвестных нам пользователей SO: таблицы, количество записей, существующие индексы и триггеры и т. Д., Поэтому очень сложно реально помочь вам здесь. – Rik

ответ

1

Итак, у вас есть таблица VAR1_TABLE по меньшей мере, три колонны, VAR1, D_TYPE и VAR1_NAME ... вы выбираете строки, которые имеют VAR1 столбец из другой таблицы, то вы присоединитесь с VAR1_TABLE на MEM_VAR1 = VAR1, а затем вы снова присоединяетесь к D_TYPE = VAR1_NAME? Можете ли вы объяснить эту часть, потому что для меня нет смысла ... почему вы сравниваете D_TYPE с VAR1_NAME? Просто потому, что вы можете это сделать, и запрос выполняется без ошибок, это не значит, что это имеет смысл.

Предполагая, что таблица R_TB_1 имеет много строк (вы, кажется, выбираете 100 000 строк, которые составляют небольшую часть всей таблицы), UNION ALL означает, что таблица проверяется дважды. Возможно, вам лучше выбрать один раз, в 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 
-3
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 
+0

Когда вы даете ответ, можете ли вы предоставить более подробную информацию о причинах? Также отступьте свой код с 4x пробелами, чтобы он отображался в цветном блоке с синтаксисом. –

+2

Не могли бы вы объяснить какое-либо улучшение между вашим и оригинальным? Кажется, вы только поместили исходный SQL в CTE, и это не улучшит производительность – Prisoner