2010-12-01 4 views
1

если я запускаю этот запросНеожиданные сметные строк в плане выполнения запроса (SQL Server 2000)

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 соответствующих строк, или MAXIMUM из 3000 строк, даже если он не знает пользователя, который будет выбран подзапросом? Почему эта огромная оценка? Проблема в том, что эта большая оценка затем влияет на другое соединение в более крупном запросе, чтобы выполнить сканирование вместо поиска. Если я запустил более крупный запрос с подзапросом, он занимает 1 мин 40 секунд. Если запустить его с жесткой кодировкой 1155, это займет 2 секунды. Это очень необычно для меня ...

Спасибо,

Chris

ответ

0

Пробовали ли вы это?

SELECT lt.user 
FROM Users u 
    INNER JOIN largeTable lt 
     ON u.User = lt.User 
WHERE u.externalId = 100 

Пожалуйста, смотрите это: subqueries-vs-joins

+1

Да, и, переписывание как соединение имеет ту же проблему! – Querylous 2010-12-02 15:39:38

1

Оптимизатор делает все возможное, но статистика и количество строк оценки идти только до сих пор (как вы видите).

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

В противном случае пришло время использовать дополнительные знания о характере ваших данных, чтобы помочь оптимизатору с помощью hints. В частности, посмотрите на опцию forceseek в подсказках index. Обратите внимание, что это может быть плохо, если ваши данные меняются позже, поэтому имейте в виду.

+0

`forceeek` - только 2008 год. ОП находится в 2000 году. – 2010-12-01 15:40:27

Смежные вопросы