Оптимизатор плана запросов SQL Server 2005 перекрывает таблицы с разбивкой по датам - PullRequest
1 голос
/ 17 ноября 2009

У нас есть ТАБЛИЦА А, разделенная по дате, и она не содержит данных за сегодняшний день, она содержит только данные за предыдущий день и за год до даты.

У нас есть ТАБЛИЦА В, также разделенная по дате, которая содержит данные за сегодняшний день, а также данные за предыдущий день, переходящие из года в дату. Вверху ТАБЛИЦЫ B находится представление View_B, которое соединяется с View_C, View_D и левыми внешними объединениями. Таблица E. Каждый из View_C и View_D выбирается из 1 таблицы и не имеет других таблиц присоединился. Так что View_B выглядит как

SELECT b.Foo, c.cItem, d.dItem, E.eItem 
FROM TABLE_B b JOIN View_C c on c.cItem = b.cItem
JOIN View_D d on b.dItem = d.dItem
LEFT OUTER JOIN TABLE_E on b.eItem = e.eItem 

View_AB объединяет ТАБЛИЦУ A и View_B в дату извлечения, а также еще одно ограничение. Так это выглядит примерно так:

SELECT a.Col_1, b.Col_2, ... 
FROM TABLE_A a LEFT OUTER JOIN View_B b 
on a.ExtractDate = b.ExtractDate and a.Foo=b.Foo

-- no where clause

При поиске данных в любом другом месте, отличном от предыдущего дня, анализатор запросов выполняет то, что ожидалось, и выполняет соединение с хеш-соответствием, чтобы завершить внешнее соединение, и считывает данные из таблицы B. объемом около 116 страниц. При запуске за предыдущий день однако оптимизатор запросов сходит с ума и использует вложенное объединение, просматривает таблицу более 7 000 раз и считывает более 8 000 000 страниц в объединении.

Мы можем подделать его / заставить его использовать другой план запроса, используя подсказки соединения, однако это вызывает любые ограничения в представлении, которое просматривает таблицу B, чтобы оптимизатор выдавал ошибку, что запрос не может быть выполнен из-за подсказок присоединения.

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

Как уже упоминалось в комментариях, мы значительно сократили влияние, создав покрытый индекс на TABLE_B, чтобы покрыть объединение в View_B, но IO все еще выше, чем было бы, если бы оптимизатор выбрал правильный план, тем более что индекс по существу избыточен для всех поисков, кроме предыдущих дней.

sqlplan на http://pastebin.com/m53789da9, извините, что это не красиво отформатированная версия.

Ответы [ 2 ]

1 голос
/ 17 ноября 2009

Если вы можете опубликовать .sqlplan для каждого из запросов, это наверняка поможет, но я догадываюсь, что вы получаете параллельный план, когда запрашиваете даты до текущего дня, а вложенный цикл равен , возможно постоянный цикл по разделам, включенным в таблицу, который затем порождает рабочий поток для каждого раздела (дополнительную информацию см. В публикации SQLCAT о параллельных планах с разделенными таблицами в Sql2005 ). Однако я не могу проверить, так ли это на самом деле, не видя планов.

0 голосов
/ 18 ноября 2009

В случае, если кто-нибудь когда-нибудь столкнется с этим, проблема, кажется, только косвенно связана со схемой разделения Несмотря на то, что мы запускаем обновление статистики каждый вечер, похоже, что SQL Server

  1. Не удалось создать статистику для ExtractDate
  2. Даже когда статистика извлечения даты была явно создана, не удалось обнаружить, что данные предыдущего дня имели данные.

Мы решили это, выполнив CREATE STATISTICS TABLE_A_ExtractDate_Stats ON TABLE_A WITH FULLSCAN. Теперь поиск предыдущего дня и случайная выборка дней дают правильный план.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...