Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / IBM DB2, WebSphere, IMS, U2, etc Новый топик    Ответить
 Какое условие по дате будет быстрее?  [new]
Semen Popov
Member

Откуда: Сыктывкар
Сообщений: 793
Здравствуйте всем!

Есть таблица TAB1 c полем DATFLD типа DATE. Индексов нет. Нужно сделать выборку записей за один месяц. Меня интересует, какая конструкция отработает быстрее:
select * from TAB1 where month(DATFLD)=? and year(DATFLD)=?
select * from TAB1 where DATFLD between ? and ?
или
select * from TAB1 where ?<=DATFLD and DATFLD<?
А может есть ещё варианты?

Спасибо
С уважением, Семен Попов
5 ноя 08, 10:30    [6395963]     Ответить | Цитировать Сообщить модератору
 Re: Какое условие по дате будет быстрее?  [new]
TORT
Member

Откуда:
Сообщений: 1095
Если есть индекс по полю с датой, то первый вариант однозначно самый медленный... Так как индекс не будет использоваться.... ИМХО, второй и третий варианты одинаковы... Я пользую второй конструкцией...
5 ноя 08, 11:09    [6396246]     Ответить | Цитировать Сообщить модератору
 Re: Какое условие по дате будет быстрее?  [new]
Victor Metelitsa
Member

Откуда: Тюмень
Сообщений: 2550
Ещё можно добавить в таблицу generated-поле (назову его Y) по выражению 100 * year(DATFLD) + month(DATFLD) и искать select * from TAB1 where YM=:month + 100 * :year. По YM неплохо не только индексировать, но и использовать в качестве измерения для MDC.
5 ноя 08, 11:46    [6396446]     Ответить | Цитировать Сообщить модератору
 Re: Какое условие по дате будет быстрее?  [new]
Mark Barinstein
Member

Откуда: Москва
Сообщений: 4946
С маркерами параметров надо иметь ввиду следующее:

План запроса строится до того, как становятся известны актуальные значения (есть, конечно, варианты с опцией компиляции reopt, но мы рассматриваем общий случай).
Если у вашей таблицы не стоит флаг volatile, то план запроса в этом случае трудно предсказать, ведь на этапе компиляции не понятно, какое кол-во строк будет в итоге выбрано.

Поэтому, если вы хотите побудить оптимизатор использовать индекс вы можете
- при установленной заранее переменной окружения DB2_SELECTIVITY=ALL:
select * from TAB1 where DATFLD between ? and ? selectivity 0.00001
- не использовать в таких запросах маркеры, а вместо них - актуальные значения параметров. Тогда оптимизатор по собранной статистике может сам, в зависимости от этих значений, выбрать оптимальный план.

Другой вариант:
- завести generated always поле:
datfld_ym generated always as (year(datfld)*100+month(datfld))
- создать индекс по нему
- использовать запросы типа:
select * from TAB1 where year(datfld)*100+month(datfld)=?
select * from TAB1 where datfld_ym=?

оптимизатор при обоих запросах должен будет использовать индекс по datfld_ym.
5 ноя 08, 11:54    [6396499]     Ответить | Цитировать Сообщить модератору
 Re: Какое условие по дате будет быстрее?  [new]
Semen Popov
Member

Откуда: Сыктывкар
Сообщений: 793
TORT
Если есть индекс по полю с датой, то первый вариант однозначно самый медленный... Так как индекс не будет использоваться.... ИМХО, второй и третий варианты одинаковы... Я пользую второй конструкцией...
Спасибо. А если индексов, использующих это поле, нет? Моё мнение, что первый вариант в любом случае будет самым медленным.
Victor Metelitsa
Ещё можно добавить в таблицу generated-поле (назову его Y) по выражению 100 * year(DATFLD) + month(DATFLD) и искать select * from TAB1 where YM=:month + 100 * :year. По YM неплохо не только индексировать, но и использовать в качестве измерения для MDC.
Спасибо. Как-нибудь учту при проектировании следующей базы. Сейчас не хотелось бы менять структуру существующей базы. Записей не много - до 50 тыс., поэтому второй вариант из предложенных мною, думаю, будет достаточным. Хотя индекс и напрашивается, но таких полей-дат, по которым производятся различные расчёты и выборки, много. Некоторые разработчики утверждают, что таблицу не стоит нагружать(?) большим количеством индексов.
Mark Barinstein
С маркерами параметров надо иметь ввиду следующее:

План запроса строится до того, как становятся известны актуальные значения (есть, конечно, варианты с опцией компиляции reopt, но мы рассматриваем общий случай).
Если у вашей таблицы не стоит флаг volatile, то план запроса в этом случае трудно предсказать, ведь на этапе компиляции не понятно, какое кол-во строк будет в итоге выбрано.

Поэтому, если вы хотите побудить оптимизатор использовать индекс вы можете
- при установленной заранее переменной окружения DB2_SELECTIVITY=ALL:
select * from TAB1 where DATFLD between ? and ? selectivity 0.00001
- не использовать в таких запросах маркеры, а вместо них - актуальные значения параметров. Тогда оптимизатор по собранной статистике может сам, в зависимости от этих значений, выбрать оптимальный план.
...
Спасибо. Таблица not volatile. Насколько разумно побуждать оптимизатор использовать индекс, если количество записей до 50 тыс? В каких условиях рекомендуется побуждать оптимизатор?
5 ноя 08, 12:31    [6396780]     Ответить | Цитировать Сообщить модератору
 Re: Какое условие по дате будет быстрее?  [new]
Mark Barinstein
Member

Откуда: Москва
Сообщений: 4946
Semen Popov
Насколько разумно побуждать оптимизатор использовать индекс, если количество записей до 50 тыс? В каких условиях рекомендуется побуждать оптимизатор?
Если ваша таблица настолько мала, что влезает на одну страницу данных, например, то индекс ей, вероятно, не нужен - страницы всё равно в память целиком считываются.
Если же нет, то возможны варианты - там желательно создать индекс и дать возможность оптимизатору оценить, использовать его или нет.
50 тыс. строк не влезут в 1 страницу...
5 ноя 08, 13:11    [6397081]     Ответить | Цитировать Сообщить модератору
 Re: Какое условие по дате будет быстрее?  [new]
Semen Popov
Member

Откуда: Сыктывкар
Сообщений: 793
Mark Barinstein
Semen Popov
Насколько разумно побуждать оптимизатор использовать индекс, если количество записей до 50 тыс? В каких условиях рекомендуется побуждать оптимизатор?
Если ваша таблица настолько мала, что влезает на одну страницу данных, например, то индекс ей, вероятно, не нужен - страницы всё равно в память целиком считываются.
Если же нет, то возможны варианты - там желательно создать индекс и дать возможность оптимизатору оценить, использовать его или нет.
50 тыс. строк не влезут в 1 страницу...
Спасибо. А если мы будем говорить только о рассчётах, а не выборке записей? Например,
select count(*),sum(FLD1) from TAB1 where DATFLD between ? and ?
Как в этом случае? Нужно ли предусматривать для вычислений индексы или побуждать оптимизатор?
5 ноя 08, 16:15    [6398609]     Ответить | Цитировать Сообщить модератору
 Re: Какое условие по дате будет быстрее?  [new]
Mark Barinstein
Member

Откуда: Москва
Сообщений: 4946
Semen Popov
А если мы будем говорить только о рассчётах, а не выборке записей? Например,
select count(*),sum(FLD1) from TAB1 where DATFLD between ? and ?
Как в этом случае? Нужно ли предусматривать для вычислений индексы или побуждать оптимизатор?
Правильнее всего будет либо избегать таких запросов, либо использовать reopt always опцию bind (но это для статического sql или для динамического, когда какой-либо package контролирует выполнение этого динамического sql - например для sql sp).
Т.е. вы должны создать такой индекс и дать оптимизатору возможность решить, какой метод доступа использовать - в зависимости от актуальных значений параметров, т.к. в этом случае нельзя заставлять оптимизатор компилировать запрос без предоставления этих значений.
Разумеется, все эти утверждения - не для крошечных таблиц.
5 ноя 08, 16:58    [6399051]     Ответить | Цитировать Сообщить модератору
 Re: Какое условие по дате будет быстрее?  [new]
Semen Popov
Member

Откуда: Сыктывкар
Сообщений: 793
Премного благодарен
5 ноя 08, 17:48    [6399593]     Ответить | Цитировать Сообщить модератору
Все форумы / IBM DB2, WebSphere, IMS, U2, etc Ответить