Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
Есть запрос Код: sql 1. 2. 3. 4. 5. 6. Он обрабатывается за 0.05 секунд, по плану запроса все хорошо используется индекс и происходит fetch только нужных записей. теперь добавляем справочник в запрос (Foreing key имеется, поле t0.BR_STATUS_ID не допускает пустых значений) Код: sql 1. 2. 3. 4. 5. 6. 7. 8. и запрос уже работает 1.5 секунды. Теперь по плану запроса он все выбирает сортирует а потом джойнит справочник. т.е. получается FETCH FIRST он использует в самом конце. Можно конечно исправить ситуацию с помощью подзапросов, но это не очень красиво выглядит. можно ли эту ситуацию исправить без подзапросов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2015, 13:30 |
|
||
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
olzhas, По этим картинкам ничего не понятно. Где описание индексов, где именно второй картинке outer и inner таблицы? Предположительно BR - outer, но на всякий... Индексы, похоже, используются разные для доступа к BR в разных запросах. Опять же, если не нравится этот план, считаете, что во 2-м случае должен использоваться другой индекс для достуа к BR - составьте оптимизационный профиль, сревните цены запросов. Можете добавить OPTIMIZE FOR 25 ROWS, проверить - не изменился ли план. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2015, 13:51 |
|
||
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
Mark Barinstein, Тут вопрос даже не в использовании индекса (таблица BR_STATUS маленька, у нее всего 8 записей), а то что fetch происходит в самом конце. я могу переписать запрос так Код: sql 1. 2. 3. 4. 5. 6. 7. или вот так Код: sql 1. 2. 3. 4. 5. 6. 7. результат не изменится, а запрос будет выполнятся как и первый за 0.05 секунд. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2015, 14:06 |
|
||
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
olzhasТут вопрос даже не в использовании индекса (таблица BR_STATUS маленька, у нее всего 8 записей), а то что fetch происходит в самом конце.Как это не в использовании индекса? Я писал про индексы на BR, а не на BR_STATUS. У вас что, в обоих случаях используется один и тот же индекс на BR? По поводу маленькой BR_STATUS. А DB2 знает об этом? Вы статистику собирали на нее и на BR? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2015, 14:29 |
|
||
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
Mark Barinstein, Я как то и не обратил внимание что используется другой индекс. Я не понимаю почему база решила именно его взять, возможно из-за того что у него самый высокий показатель sequntal_page (это к вопросу из предыдущего моего топика). Я сделал реогранизацию таблицы а потом и индексов. план запроса поменялся, и запросы стали выполнятся уже 0.3 секунды. Теперь он использует full table scan. Что по планам запроса выглядит как выгоднее, но по времени он выполняется дольше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2015, 09:18 |
|
||
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
Я так понимаю. В пером случае обрезание происходит на этапе fetch по мене загрузки данных. Во втором случае обрезание происходит на этапе sort, но для того что бы сделать sort надо загрузить все данные с таблицы. и вот тут самое интересное оптимизатор не использует IXSCAN + FETCH потому что это дороже чем просто TBSCAN (34 тыс против 15 тыс) получается что он не смотрит на количество указанное в fetch frist N rows olny. Если это так тогда почему в первом случае он тоже не использует TBSCAN, это ведь дешевле. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2015, 09:33 |
|
||
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
если переписать запрос вот так Код: sql 1. 2. 3. 4. 5. 6. 7. то получим такой план запрос. какой он и должен быть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2015, 09:37 |
|
||
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
Чтобы понимать "почему", желательно понимать принципы расчёта стоимости, я знаю лишь одну-единственную книжку, но и та про Oracle. Вкратце и очень сильно упрощённо, основная часть стоимости обычно(!) идёт с предсказанного количества чтения, но не голое количество блоков, а с учётом предсказанной одноблочности и мультиблочности, и считается с использованием OVERHEAD И TRANSFERRATE табличного пространства. И расчёты эти, по большому счёты, вилами на воде писаны, ибо основаны на статистике (а средний случай совсем не обязан подходить к вашему частному), часто основаны на догадках и часто не могут учитывать реальную обстановку. А быстрее всего ваш запрос, наверное, будет работать при UNIQUE INDEX ... ON NABRK.BR(BR_id) INCLUDE(BR_STATUS_ID). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2015, 10:15 |
|
||
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
olzhas, FETCH FRIST N ROWS не оказывает на оптимизатор влияния. Это только указание прекратить возврат записей после N записей. Если вы хотите повлиять на оптимизатор, используйте в дополнение к этому OPTIMIZE FOR N ROWS. Например, OPTIMIZE FOR 1 ROW ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2015, 10:30 |
|
||
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
Mark Barinstein, Вот спасибо! Теперь все работает так как надо. итоговый запрос Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2015, 11:10 |
|
||
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
Мысли по этому поводу: Принудив использовать индекс, принуждаете проход по нему (одноблочными чтениями) вперемешку со чтениями данных из таблицы (тоже, скорее всего, одноблочными чтениями). По сравнению с этим, оптимизатор считает, что проще считать таблицу многоблочными чтениями и рассортировать. Марк предложил сказать оптимизатору через OPTIMIZE FOR 1 ROWS, что вы далеко не пойдёте, так что всю таблицу читать будет не надо - и когда есть подходящий индекс, тут он точно выгоден. Нужно просто пройти индекс сверху вниз (пара-тройка-четвёрка чтений страниц индекса) и одно чтение табличной страницы. Это по цене много меньше того, чтобы прочитать все страницы индекса и все страницы таблицы (в варианте без OPTIMIZE FOR), вместо чего было и выбрано простое сканирование таблицы с сортировкой. До этого, я предложил не обращаться к таблице (путём UNIQUE INDEX ... ON NABRK.BR(BR_id) INCLUDE(BR_STATUS_ID).). Менее, скажем так, правильный вариант (если не прибавить OPTIMIZE FOR к нему). Не исключено, что планом было бы полное чтение индекса, а затем его сортировка(!). Либо читать индекс по порядку одноблочными чтениями - невыгодно, если он не совсем маленький, либо быстренько считать многоблочными - выгодно, если он размером меньше таблицы, но при этом порядок не гарантирован (в Oracle так, и нет причин, чтобы в DB2 было не так). OPTIMIZE FOR 25 ROWS. возможно, более точное. OPTIMIZE FOR 1 ROWS - это чтобы принудить к использованию индекса на NABRK.BR наверняка. Но вот что будет с cardinality дальше? План INNER JOIN NABRK.BR_STATUS t1 ON t0.BR_STATUS_ID = t1.BR_STATUS_ID может зависеть от неё. То есть, 1 раз мы ищем в таблице NABRK.BR_STATUS или 25 раз - разница может быть (или не быть). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2015, 14:00 |
|
||
|
fetch first and join
|
|||
|---|---|---|---|
|
#18+
Victor Metelitsa, Мой пример часть большого запроса. при одном join OPTIMIZE FOR 25 ROWS работает, но при больших количествах (у меня их 8) оптимизатор уже предпочитает полное сканирование таблицы, поэтому я и поставил OPTIMIZE FOR 1 ROWS, что бы уже наверняка. строить еще один индекс с include, нет смысла при нескольких join. В целом проблема была в том что оптимизатор не понимал что требуется небольшое количество записей. конструкция OPTIMIZE FOR 1 ROW решает эту проблему. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2015, 14:16 |
|
||
|
|

start [/forum/topic.php?fid=43&msg=39113737&tid=1600694]: |
0ms |
get settings: |
10ms |
get forum list: |
16ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
73ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
49ms |
get tp. blocked users: |
1ms |
| others: | 279ms |
| total: | 452ms |

| 0 / 0 |
