2010-11-19 5 views
1

У меня есть запрос, как:Sql запрос с тем, где исполнением пункта

(q1) 
select a,b,c,d from abc 
where param='x' 

union 

(q2) 
select e,f,g,h from abc 
where param='y' 

Я хочу знать, если значение <param>='y' будет QUERY1 получить выполнено ?? Это потому, что recodset «abc» очень большой и фактический запрос включает в себя 5-6 союзов по одному и тому же параметру (u может видеть, что требуется только один запрос данных за раз). Поэтому, если данные извлекаются из всех запросов и отфильтрованных в соответствии с предложением where, это будет большой накладной, тогда как при фильтрации до этого только один из 5 запросов действительно выполняется.

Благодаря Himanshu

+0

Кроме того, я использую Oracle DB (идентификатор, который влияет на ответ) – Himz

+1

Постарайтесь узнать больше о базовых концепциях SQL; в то же время для каждого SQL вы можете выдавать EXPLAIN ... и RDBMS покажет вам план (который потребует от вас изучения еще нескольких концепций, но в конечном счете очень полезно знать, хотите ли вы понимать тонкости SQL против реальных путей доступа к данным и алгоритмов). – Unreason

+0

Я иду по этой ссылке. Этот параметр очищает переменные связывания http://www.akadia.com/services/ora_bind_variables.html – Himz

ответ

2

Если вы пишете что-то вроде

where 1 = 2 

, которые могут быть оценены, не прикасаясь к базе данных, то Oracle будет достаточно умен, чтобы пропустить доступа к таблицам.

Это должно работать даже с переменными привязки.

where ? = ? 

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

+0

Спасибо, Его переменная связывания. – Himz

+0

Что означает, что я могу использовать как можно больше профсоюзов, не имея большого количества накладных расходов? – Himz

+1

Оптимизатор запросов должен иметь возможность находить и отбрасывать мертвый код в вашем запросе. Накладные расходы по сравнению с чем? Будет легче, если вы устраните бесполезную часть самостоятельно. – Thilo

2

Если «param» - это столбец в abc, это очень помогло бы вам индексировать этот столбец.

Но самое большое влияние на производительность в вашем запросе, вероятно, является «объединением», поскольку Oracle необходимо отфильтровывать повторяющиеся строки. В зависимости от размера вашего набора результатов это довольно тяжелая операция (сортировка, удаление дубликатов). Если вы не связаны с повторяющимися результатами (или если они просто невозможно из-за определения запросов), использовать «объединение всех»:

select a,b,c,d from abc 
union all 
select e,f,g,h from abc 
+0

- переменная связывания (не столбец) – Himz

+0

Запрос таков, что получает только один из всех данных объединений в зависимости от значения . – Himz

+4

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

1

На мой взгляд, это ленивый программирования и вы пытаетесь чтобы база данных выполняла работу приложения. Простое заявление «если» с кучей конкатенаций - это все, что вам нужно.

+0

Я думаю, что самонадеянно говорить, что это «лениво» - вы не знаете контекста, в котором этот запрос требуется. Во-первых, это может быть в контексте, который не позволяет PL/SQL. Плюс, где говорится, что выполнение такого рода вещей должно быть «работой приложения»? –

2
select * 
from (
select 1 INDICATOR, 
     a, b, c 
from abc 
union all 
select 2 INDICATOR, 
     a, b, c 
from abc) 
where indicator = 1; 

Это не будет выполнять второй запрос в объединении. Как вы можете видеть в плане выполнения, есть Фильтр, в котором говорится, что «null не является нулевым». Однако у многих профсоюзов есть значительные накладные расходы.

0

Вопрос подсказывает мне, что вы хотите избежать двух полных сканирований таблицы по набору данных. Эта техника может помочь вам.

WITH 
base AS 
(
    SELECT a,b,c,d,e,f,g,h FROM abc -- all columns of interest 
    WHERE param IN ('x', 'y')  -- all rows of interest 
), 
q1 AS 
(
    select a,b,c,d from base  -- one specific subset 
    where param='x' 
), 
q2 AS 
(
    select e,f,g,h from base  -- the other specific subset 
    where param='y' 
) 
SELECT a,b,c,d FROM abc    -- then the union of the sets 

UNION 

SELECT e,f,g,h FROM abc    -- that you are interested in. 

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

Если набор различных значений в параметре мал, может быть полезно построить histograms.

Как и во всех случаях Oracle, ваш пробег может отличаться.

Мне было бы интересно услышать, как все это получается для вас.

+0

Спасибо. Я решил заняться моей текущей реализацией. Теперь рассмотрим ваше предложение. Надеюсь, что эта штука работает правильно для меня. – Himz

0

Как указывали другие, Oracle будет удалять ветви мертвого кода из вашего запроса после оценки переменной привязки. Вы можете заменить союз на «union all» (а не на то, что это имеет значение в любом случае), но намерение разработчика проявляется более четко (я, разработчик не ожидал, что здесь нет дубликатов).

Один открытый вопрос (для меня в любом случае): знаете ли вы, что тип данных «a» соответствует «e» и «b» соответствует «f» и т. Д.?

На самом деле, я никогда не реализовывал это сам, только читал об этом, поэтому кто-то хочет подтвердить, что я говорю. Но совершенно другой подход может заключаться в создании хранимой процедуры, которая принимает параметр. Процедура имеет один курсор для каждого ожидаемого значения параметра. Затем вы можете проверить (IF) значение параметра и вернуть курсор ref.

+0

Я не понимаю, что вы подразумеваете под типами данных. В союзах все столбцы должны быть одинаковыми, и если нам не нужен один конкретный столбец, мы делаем «null как ».Таким образом, «a» так же, как «e», а «b» совпадает с «f». Я не могу создать хранимую процедуру. Может использовать только SQL. Спасибо – Himz

+0

Вы не делились DDL, поэтому я не мог знать. – Ronnis