Условие простого сравнения строк делает запрос более длинным - PullRequest
3 голосов
/ 22 июня 2019

Запрос № 1 из приведенного ниже кода при самом первом запуске занимает 1-2 секунды, второй, а затем выполняется менее 0,1 секунды. Между тем запросы № 2 и № 3 всегда выполняются в течение 0,1 - 0,2 секунд. Есть ли объяснение этому поведению? Я бы понял, если бы это было наоборот из-за ложного состояния в # 1.

Я пока не предоставляю план выполнения, потому что это представление немного сложнее, и я не уверен, что сам план поможет. Но я буду, если это действительно требуется

1

SELECT
doc_id, line_num, load_id, ord_qty
FROM someview v
WHERE doc_id = 2987541 and 'A'='X' and v.iter_num = 
(select max(iter_num) from someview where doc_id=v.doc_id);

2

SELECT
doc_id, line_num, load_id, ord_qty
FROM someview v
WHERE doc_id = 2987541 and v.iter_num = 
(select max(iter_num) from someview where doc_id=v.doc_id);

3

SELECT
doc_id, line_num, load_id, ord_qty
FROM someview v
WHERE doc_id = 2987541 and 'X'='X' and v.iter_num = 
(select max(iter_num) from someview where doc_id=v.doc_id);

1 Ответ

0 голосов
/ 22 июня 2019

Разница во времени выполнения для запроса № 1 может быть связана с жестким разбором и / или холодным буферным кешем.

После первого запуска проанализированный кэшированный запрос находится в общем пуле, и блоки данных были считаны в буферный кеш в общей памяти (при условии, что они не сразу устаревают из-за загруженности системы).Таким образом, второй запуск и далее, как правило, должен быть быстрее.Вы можете проверить, является ли более длительное начальное время выполнения запроса № 1 из-за жесткого синтаксического анализа, запустив запрос, очистив связанный курсор из общего пула, запустив его снова и посмотрев, останется ли время выполнения на 1-2 секунды.Хотя весь общий пул можно очистить с помощью команды ALTER SYSTEM FLUSH SHARED POOL, менее навязчивым подходом является очистка вашего конкретного курсора.Ссылки ниже показывают, как это сделать.

DBMS_SHARED_POOL.PURGE

Как очистить отдельный объект из общего пула

В качестве альтернативы, вы можете проследить ваш сеанс и использовать tkprof, чтобы увидеть, сколько времени затрачивается на этапы анализа, выполнения и выборки для запроса № 1, и сравнить результаты с последующими запусками.Подробности см. Ниже:

трассировка SQL и TKPROF

Что касается запросов № 2 и № 3, если вы выполняете их сразу после запроса № 1, тогдаони могут работать быстрее из-за того, что запрос №1 уже прогрел кеш.К сожалению, не существует простого способа выборочной очистки блоков данных из буферного кеша, как вы можете с помощью проанализированных операторов в общем пуле.Хотя оператор ALTER SYSTEM FLUSH BUFFER CACHE может очистить кэш, это действительно плохая идея сделать это в производственной системе, так как это может вызвать огромный всплеск физического ввода-вывода во время повторного заполнения кеша.Выполнение этого в изолированной непроизводственной системе может быть приемлемым.

Возвращаясь к синтаксическому анализу, запрос № 3 может использовать тот же проанализированный запрос, что и № 1, в зависимости от того, как установлен параметр cursor_sharing, что значительно сэкономит время анализа.

CURSOR_SHARING параметр

Наконец, tkprof и другие инструменты, на которые ссылается этот ответ, требуют повышенных привилегий в базе данных, поэтому вам может потребоваться помощь вашего администратора базы данных.

...