|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
Допустим есть такой запрос: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9.
который используется в pl/sql-процедуре (into). Суть задачи - вытащить первое значение из результата, удовлетворяющему некоторому условию (where t.deptno = 20), но не рандомное, а по приоритетам (order by). Агрегатная функция min используется, чтобы вернуть NULL, если подзапрос не вернёт ни одной записи (ну т.е. чтобы не писать exception-блок). А вот аналог с использованием аналитической функции min: Код: plsql 1. 2. 3. 4.
План выполнения первого: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
План второго: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Казалось бы, второй вариант более выгодный. И он выглядит элегантнее (если выбирается не более одного столбца). Однако многократный прогон процедуры в цикле показывает, что первый вариант на копейку, но быстрее. (гонял на Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production) Есть ли какие-то весомые аргументы в пользу второго варианта? ... |
|||
:
Нравится:
Не нравится:
|
|||
18.08.2019, 20:25 |
|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
delphinotes, 21757716 А вообще забей и оставь второй вариант: 1. Простой и интуитивно понятный, т.е. легкосопровождаемый 2. Более стабильный (не так зависит от различных оптимизаций) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2019, 01:26 |
|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
xtender, спасибо. На свежую голову походил по ссылкам, погуглил... для своей задачи увидел, что стоит сделать соответствующий индекс, а также нарисовался третий вариант с row_number: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9.
план которого: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
почти такой же, как и в первом варианте. И работает с такой же скоростью, как и первый вариант. И будет выглядеть не громоздко, если надо выбрать несколько столбцов. (есть и четвёртый вариант с first row, но для Oracle 12) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2019, 07:19 |
|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
delphinotesсделать соответствующий индексАга. Для пущей показательности в планах по таблице emp только индекса не хватает. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2019, 07:31 |
|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
delphinotes, оба варианта не очень.... попробуй for cc in c loop v:= cc.asd; exit; end loop; и проверь по скорости на миллионе итераций. очень полезно бывает) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2019, 13:57 |
|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
delphinotesДопустим есть такой запрос: Серебряной пули нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2019, 14:36 |
|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
Vintdelphinotes, оба варианта не очень.... попробуй for cc in c loop v:= cc.asd; exit; end loop; и проверь по скорости на миллионе итераций. очень полезно бывает) говорят что в новых версиях for может "подчитать" за раз/сразу множество строк (аля форалл) ..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2019, 14:42 |
|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
Stax, так он всегда читал по 100 строк, нет? но советую проверить производительность. аналитика и группировка очень дорогие операции. сортировка и чтение сильно дешевле. по крайней мере было на 11.2 и 12.2 ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2019, 14:52 |
|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
Vintdelphinotes, оба варианта не очень.... попробуй for cc in c loop v:= cc.asd; exit; end loop; и проверь по скорости на миллионе итераций. очень полезно бывает) Откуда миллион итераций? Подтягивать какие то значения в дополнение к основному запросу в цикле на миллион итераций, решение прямо скажем не очень, не лучше ли написать один запрос? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2019, 15:04 |
|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
Хмъ, ну как бы конкретно в данном случае за вариант с keep() будут и бритва оккама, и правило большого пальца, и кисс... Vintаналитика и группировка очень дорогие операции. сортировка и чтение сильно дешевле. по крайней мере было на 11.2 и 12.2зависит от... очень зависит... что предыдущий приведенный мной линк уже показал ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2019, 15:06 |
|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
Vintтак он всегда читал по 100 строк, нет?В старых версиях for читал по одной строке. Обратное от "старый" - Stax почти не наврал в сравнительных прилагательных. Где-то в 11.1 попадал на пару багов этой оптимизации, предположу это и есть первый релиз. Vintаналитика и группировка очень дорогие операции. сортировка и чтение сильно дешевле.Группировка и аналитика суть есть сортировка, но благодаря stop key/push rank требуют меньше памяти. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2019, 15:17 |
|
Какой запрос лучше? first vs rownum
|
|||
---|---|---|---|
#18+
Vintтак он всегда читал по 100 строк, нет? Нет. Если склероз мне не изменяет, то где-то в 10 или 11 обычный for-loop научили фетчить по 5 строк на дефолтном уровне оптимизации PL/SQL. По крайней мере в 10046 было видно "по 5". Дальше не следил :) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.08.2019, 15:19 |
|
|
start [/forum/topic.php?fid=52&msg=39851132&tid=1882179]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
38ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
49ms |
get tp. blocked users: |
1ms |
others: | 257ms |
total: | 391ms |
0 / 0 |