Почему запрос с вложенным выбором стоит дешевле, чем запрос с константой в Oracle - PullRequest
6 голосов
/ 07 июля 2010

У меня есть SQL-таблица с несколькими миллионами записей, и я попытался узнать, сколько записей старше 60 дней (Oracle 11.2.0.1.0).

Для этого эксперимента я использовал 3 разныхверсии оператора SELECT:
(Стоимость указана TOAD для Oracle V. 9.7.2.5)

  1. select count(*) from fman_file<br> where dateadded >= (select sysdate - 60 from dual)
    Стоимость: 65

  2. select count(*) from fman_file<br> where dateadded >= sysdate - 60
    Стоимость: 1909

  3. select count(*) from fman_file<br> where dateadded >= sysdate - numtodsinterval(60,'day')
    Стоимость: 1884

  4. select count(*) from fman_file where dateadded >= '10.10.2009'
    Стоимость: 1823
    (10.10.2009 - просто пример даты !!!)

У меня нет точного времени-значения для всех запросов, но первый действительно был самым быстрым.

Поэтому я попробовал еще несколько запросов select с другими подвыборками (например, (выберите 1000 из двойного)), и они были (иногда WAY) быстреечем другие с постоянными значениями.Даже кажется, что этот «WHATEVER» (ошибка / особенность) происходит и в MySQL.

Так может кто-нибудь сказать мне, почему первый запрос (намного) быстрее других?

Greetz

PS: Это не о sydate!Вопрос в том, ПОЧЕМУ ВАРИАЦИЯ С (ВЫБРАТЬ) БЫСТРЕЕ, ЧЕМ ДРУГИМИ?(с небольшим акцентом на Select-Variation (1.) и Constant-Variation (4.))

Ответы [ 5 ]

3 голосов
/ 07 июля 2010

Нашел некоторые подсказки в моем экземпляре "Основы Oracle на основе затрат" Джонатана Льюиса в главе 6 "Удивительное системное событие".Это относится к 9i, возможно, к более поздним версиям.

Оптимизатор обрабатывает sysdate (и trunc (sysdate) и некоторые другие функции sysdate) как известные константы во время разбора, но sysdate + Nстановится неизвестным и получает ту же обработку, что и переменная связывания, что означает фиксированную 5% селективность.(Обратите внимание, в частности, что sysdate + 0 даст кардинальность, отличную от sysdate.)

Очевидно, оптимизатор также распознает select sysdate from dual как известную константу.

1 голос
/ 07 июля 2010

Том Кайт :

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

0 голосов
/ 14 февраля 2014

вместо использования (выберите sysdate - 60 из dual) Я бы рекомендовал вам использовать переменную связывания, значение которой рассчитывается до того, как запрос будет выполнен

0 голосов
/ 07 июля 2010

Вы можете попробовать использовать Explain Plan.Это покажет вам, что делают запросы, и различия между ними.

Несколько ссылок на настройку и использование плана объяснения:

http://download.oracle.com/docs/cd/B10500_01/server.920/a96533/ex_plan.htm

http://www.adp -gmbh.ch / ора / explainplan.html

0 голосов
/ 07 июля 2010

Вы перепробовали числа 2-4 с () вокруг вычисления после> = - мне кажется, первое утверждение - единственное, где оно вычисляет это значение один раз - для всех остальных, на которые оно пересчитываеткаждый рядНапример:

select count(*) from fman_file where dateadded >= (SELECT sysdate - 60) 

select count(*) from fman_file where dateadded >= (SELECT (sysdate - numtodsinterval(60,'day'))

select count(*) from fman_file where dateadded >= (SELECT CONVERT(datetime,'10.10.2009')) 

NB - не знаю синтаксис для преобразования в datetime в Oracle - но вы поняли идею.

...