2009-07-15 3 views
2

У меня есть два запроса, и я хочу понять, что лучше с точки зрения производительности и памяти. Я также приветствую другие альтернативы для этих двух.Производительность и память Oracle

Запрос 1:

SELECT DISTINCT a.no, 
    a.id1   , 
    a.id2 
    FROM tbl_b b   , 
     tbl_a a , 
     tbl_c c , 
     tbl_d d 
    WHERE (
      b.id1    = a.id1 
     AND a.id1    = c.id1 
     AND upper(c.flag)  = 'Y' 
     AND c.id1    = d.id1 
    ) 
    OR (
      b.id2    = a.id2 
     AND a.id2    = c.id2 
     AND upper(c.flag)  = 'Y' 
     AND c.id2    = d.id2 
) 
AND d.id3 = 10 

Здесь столы б, г очень большие таблицы работает более 500000 до миллионов строк, а в таблице а является относительно меньше.

Мое требование состоит в том, чтобы забрать только те записи из таблицы a, идентификатор которых (либо id1 или id2) доступен в таблицах b, c, d, удовлетворяющих некоторым другим условиям.

Альтернативный запрос, который я имею в руке

Запрос 2:

SELECT DISTINCT a.no, 
    a.id1    , 
    a.id2 
    FROM tbl_a a 
    where exists (select a.id1, a.id2 from   
      tbl_c c where ((a.id1 = c.id1 or a.id2 = c.id2) 
      AND upper(c.active_flag) = 'Y')) 
    and exists (select a.id1, a.id2 from 
      tbl_b b where b.id1 = a.id1 or b.id2 = a.id2) 
    and exists (select a.id1, a.id2 from tbl_d d 
       where (a.id1 = d.id1 or a.id2 = d.id2) 
       AND d.id3 = 10) 

Что лучше производительность мудрым? Я понимаю, что запрос два занимает меньшее пространство, чем запрос 1. Но как выбрать лучший?

ответ

4

Способ выбора лучшего - попробовать как реалистичные данные, так и посмотреть, какие из них лучше всего подходят. Если они являются логически эквивалентными запросами, то вполне вероятно, что оптимизатор придумает один и тот же план для обоих, что вы сможете увидеть, используя AUTOTRACE или TKPROF или аналогичные инструменты.

+0

Привет, Тони, моя ошибка, которая была .. Я пропустил парантез. Теперь я обновил запрос, это ((a или b) и c) в моем состоянии. – 2009-07-15 12:59:45

+0

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

+0

+1, всегда старайтесь, когда это возможно. – DCookie

1

Update:

Смотрите эту статью в своем блоге подробности производительности:

Это один будет наиболее эффективным:

SELECT a.no, 
     a.id1, 
     a.id2 
FROM tbl_a a 
WHERE EXISTS 
     (
     SELECT 1 
     FROM tbl_b b 
     WHERE b.id1 = a.id1 
     ) 
     AND EXISTS 
     (
     SELECT 1 
     FROM tbl_c c 
     WHERE c.id1 = a.id1 
       AND UPPER(c.flag) = 'Y' 
     ) 
     AND EXISTS 
     (
     SELECT 1 
     FROM tbl_d d 
     WHERE d.id1 = a.id1 
       AND d.id3 = 10 
     ) 
UNION 
SELECT a.no, 
     a.id1, 
     a.id2 
FROM tbl_a a 
WHERE EXISTS 
     (
     SELECT 1 
     FROM tbl_b b 
     WHERE b.id2 = a.id2 
     ) 
     AND EXISTS 
     (
     SELECT 1 
     FROM tbl_c c 
     WHERE c.id2 = a.id2 
       AND UPPER(c.flag) = 'Y' 
     ) 
     AND EXISTS 
     (
     SELECT 1 
     FROM tbl_d d 
     WHERE d.id2 = a.id2 
       AND d.id3 = 10 
     ) 

Oracle не слишком хорош в оптимизации OR условий.

Разделение запросов должно помочь оптимизатору использовать два разных плана выполнения для каждой из частей OR.

Вы должны создать следующие показатели:

tbl_b (id1) 
tbl_b (id2) 
tbl_c (id1, UPPER(flag)) 
tbl_c (id2, UPPER(flag)) 
tbl_d (id1, id3) 
tbl_d (id2, id3) 

Обратите внимание на функции на основе индекса на UPPER(flag), вы должны создать его именно таким образом.

+0

Вы изменили запрос - ('y', 'Y')! = ('Y') Союз вызывает сортировку по возвращаемым наборам результатов. Отсутствует первый выбор «И d.id3 = 10» – user60890

+2

@glenn: оригинальный запрос сказал UPPER (флаг) = 'Y', что эквивалентно значению IN ('y', 'Y') – Quassnoi

+2

@glenn: UNION не обязательно вызывает сортировку, это зависит от метода, выбранного оптимизатором: SORT UNIQUE или HASH UNIQUE, последний не сортирует – Quassnoi

1

Информация не достаточна, чтобы дать вам надежный ответ. Есть ли какие-либо индексы? Для TBL_C, какой процент записей имеет FLAG = 'Y' и сколько записей в этой таблице? Для таблицы TBL_D, сколько записей с ID3 = 10? Является ли 10 жестко закодированным значением или может быть любое заданное значение (и вы будете использовать переменные связывания - правильно?)

Тони прав насчет использования autotrace и tkprof, чтобы узнать, какой из них выполняет наименьшее количество работы. Обычно я начинаю с получения SQL_PLAN для каждого и просто запускаю их, если это то, что я ожидаю. Если количество данных и правильных индексов не должно превышать второй или два.

+0

Существует достаточно информации, чтобы указать, какие индексы необходимы. – jva

+0

Уверен? Насколько велики таблицы? Мы знаем о количестве записей, но не о том, насколько они велики. Поля FLAG установлены на «Да» на 1 процент или 99 процентов записей? То же самое для TBL_D? У меня возникло гораздо больше проблем с запросами с использованием индексов, когда они должны использовать полные проверки, а затем наоборот. Индексы не злые, но они тоже не решают. – user60890

Смежные вопросы