Запрос SQL с выполнением предложения where - PullRequest
1 голос
/ 19 ноября 2010

У меня есть запрос вроде:

(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 ?? Это связано с тем, что набор записей «abc» очень большой, и фактический запрос включает 5-6 объединений с одним и тем же параметром (вы можете видеть, что одновременно требуются только одни данные запроса). Таким образом, если данные извлекаются из всех запросов и фильтруются в соответствии с предложением where, тогда это будет большим дополнительным расходом, тогда как при фильтрации до этого фактически выполняется только один из 5 запросов.

Спасибо Himanshu

Ответы [ 6 ]

2 голосов
/ 19 ноября 2010
select *
from (
select 1 INDICATOR,
       a, b, c
from abc
union all
select 2 INDICATOR,
       a, b, c
from abc)
where indicator = 1;

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

2 голосов
/ 19 ноября 2010

Если 'param' является столбцом в abc, это очень поможет при индексировании этого столбца.

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

select a,b,c,d from abc
union all
select e,f,g,h from abc
2 голосов
/ 19 ноября 2010

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

where 1 = 2

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

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

where ? = ?

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

1 голос
/ 19 ноября 2010

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

0 голосов
/ 03 декабря 2010

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

Один открытый вопрос (мне в любом случае) это: Можете ли вы знать наверняка, что тип данных "a" соответствует "e" и "b" соответствует "f" и так далее?

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

0 голосов
/ 26 ноября 2010

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

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.

Поскольку вы выполняете поиск по параметру, индекс будет иметь большое значение, позволяя заменить FULL TABLE SCAN менее затратным INDEX.scan.

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...