У меня есть следующий запрос (это упрощенная версия гораздо более сложный запрос):
SELECT * FROM TPM_TASK
WHERE (PROJECTID, VERSIONID) IN ((3,1), (24,1), (4,1))
В коде я буду строить этот (PROJECTID,VERSIONID)
список ключей программно, и этот список потенциально может состоять из пары тысяч пар.
Мой вопрос заключается в том, как Oracle будет оптимизировать этот запрос, учитывая, что ProjectId
и VersionId
индексируются. Будет ли список преобразован в хеш-таблицу, подобно соединению
с временной таблицей? Или поиск каждого ключа будет выполняться по одному?
Я попытался выполнить этот запрос в своей тестовой базе данных и получил:
SELECT STATEMENT 68.0 68 2989732 19 8759 68 ALL_ROWS
TABLE ACCESS (FULL) 68.0 68 2989732 19 8759 1 TPMDBO TPM_TASK FULL TABLE ANALYZED 1
Однако я считаю, что в этой базе данных недостаточно данных для сканирования индекса. Я попробовал запрос на производстве и получил:
SELECT STATEMENT 19.0 19 230367 23 9683 19 ALL_ROWS
INLIST ITERATOR 1
TABLE ACCESS (BY INDEX ROWID) 19.0 19 230367 23 9683 1 TPMDBO TPM_TASK BY INDEX ROWID TABLE ANALYZED 1
INDEX (RANGE SCAN) 4.0 4 64457 29 1 TPMDBO TPM_H1_TASK RANGE SCAN INDEX ANALYZED 1
Кажется, это попало в индекс, однако я не уверен, что означает INLIST ITERATOR. Я предполагаю, что это означает, что Oracle перебирает список и выполняет доступ к таблице для каждого элемента в списке, что, вероятно, было бы не слишком эффективно с тысячами ключей. Однако, возможно, Oracle достаточно умен, чтобы оптимизировать это лучше, если я на самом деле действительнодал ему несколько тысяч ключей.
ПРИМЕЧАНИЕ. Я не хочу загружать эти ключи во временную таблицу, потому что, честно говоря, мне не нравится, как временные таблицы работают в Oracle, и обычно они приводят к большему разочарованию, чем пользы ( во всяком случае на мой не экспертный взгляд.)