pratap420 Ответов: 1

Порядок выполнения запроса на where и view в SQL server


Всем Привет,

У меня есть сложное представление, которое имеет 6 таблиц внутренних соединений и максимальную функцию на нем.

Из 6 таблиц только в одной таблице содержится 100 миллионов простых данных (без полей).

Я запускаю один запрос, который выглядит так
Select * 
  from ComplexView 
  where id in (Select id from AnotherView where dt between 'somedate' to 'someotherdate')


Я проверил индексы и статистику для всех базовых таблиц, которые используются в ComplexView,и все они имеют среднюю фрагментацию менее 10% .

Когда я запускаю этот запрос, это занимает более 2 часов. Но если я перестрою индексы и обновлю статистику,
он дает результат через 10 секунд. Кое-как, через некоторое время (в prod) его снова берут на 2 часа.

ComplexView:

Выберите id, max(case )
из таб1.... таб6 (все внутренние соединения r)
группа по идентификатору


Видя план выполнения, я запутываюсь, является ли сначала его выполнение условием where или логикой просмотра.

В общем случае, где предложение будет рассмотрено в первую очередь или просмотр выполнения в первую очередь?

Может ли кто-нибудь, пожалуйста, подсказать, что может быть причиной проблемы perf?. Без изменения вида и без перестройки индексов каждые 2 часа.??

Заранее спасибо

Что я уже пробовал:

Для целей тестирования я просто использую результирующий набор
Select id from AnotherView where dt between 'somedate' to 'someotherdate'
во временную таблицу и выполните следующий запрос
Select * from ComplexView where id in (select id from #tmp) 

это продолжалось почти 30 секунд.

1 Ответов

Рейтинг:
2

AnvilRanger

Вы говорите, что после перестройки индексов и статистики требуется "некоторое время", чтобы вернуться к 2-часовому выполнению вашего запроса. Как долго это когда-нибудь? Часы, дни, недели?

Похоже, что вам нужно создать план обслуживания для вашей БД. Это включает в себя перестройку индекса и т. д. С таблицей из 100 + миллионов строк, если это таблица транзакций с большим количеством записей / обновлений/удалений, индексы могут быстро фрагментироваться.

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


0x01AA

Чудеса также не могут быть выполнены MSSQL. В 5 для этого

pratap420

Спасибо за ваше решение. Иногда здесь бывает только 4 часа. Хуже всего то, что только в день мы можем иметь около 1000 строк записи/обновления/удаления для этой огромной таблицы.

План технического обслуживания выполняется два раза в неделю.

AnvilRanger

Добавлено небольшое примечание к решению, которое вы, возможно, захотите рассмотреть.

CHill60

5 б.
Я бы также предложил использовать join, а не IN, и перечислять конкретные столбцы, а не использовать *

CHill60

Кроме того, это может быть совершенно другой запрос, который портит план выполнения. Видишь https://docs.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-freeproccache-transact-sql

AlwzLearning

Я бы порекомендовал использование соединений, а не в подзапросе .

Причина: сначала он выполнит подзапрос, а затем сканирует каждую запись, чтобы проверить, существует ли запись, которую вы ищете, и соответственно извлекает результаты.

С другой стороны , когда вы используете join с условием where, он будет выбирать только записи условия where и соответственно извлекать результаты из join.