если я выполню этот запрос
select user from largetable where largetable.user = 1155
(обратите внимание, что я опрашиваю пользователя, чтобы свести это к простейшему случаю)
И посмотрите на план выполнения, поиск индекса запланирован [largetable имеет индекс на пользователя], и предполагаемые строки - правильные 29.
Но если я сделаю
select user from largetable where largetable.user = (select user from users where externalid = 100)
[результатом подзапроса является одно значение 1155, как и выше, когда я жестко его кодирую]
Оптимизатор запросов оценивает 117 000 строк в результате. В большой таблице около 6 000 000 строк, 1700 строк в пользователях. Конечно, когда я запускаю запрос, я получаю правильные 29 строк, несмотря на огромные оценочные строки.
Я обновил статистику с помощью fullscan для обеих таблиц соответствующих индексов, и когда я смотрю на статистику, они кажутся правильными.
Следует отметить, что для любого конкретного пользователя в крупной таблице не более 3000 строк.
Итак, почему предполагаемый план выполнения показывает такое большое количество предполагаемых строк? Разве оптимизатор не должен знать, основываясь на статистике, что он ищет результат, который имеет 29 соответствующих строк, или МАКСИМАЛЬНОЕ из 3000 строк, даже если он не знает пользователя, который будет выбран подзапросом? Почему эта огромная оценка? Проблема в том, что эта большая оценка затем влияет на другое объединение в более крупном запросе, чтобы выполнить сканирование вместо поиска. Если я выполняю больший запрос с подзапросом, это занимает 1мин 40 секунд. Если запустить его с жестким кодом 1155, это займет 2 секунды. Это очень необычно для меня ...
Спасибо
Chris