Изменение дизайна запросов для повышения производительности

Это больше похоже на вопрос дизайна, но также связан с оптимизацией SQL.

Мой проект должен импортировать большое количество записей в базу данных (более 100 тыс. Записей). В то же время у проекта есть логика для проверки каждой записи, чтобы убедиться, что она соответствует критериям, которые можно настроить. Затем он будет отмечать запись как предупреждение или предупреждение в базе данных. Проверка вставки и предупреждения выполняется в рамках одного процесса импорта.

Для каждого критерия он должен запрашивать базу данных. Запрос должен объединяться в две другие таблицы и иногда добавлять дополнительный вложенный запрос внутри условий, таких как

select * from TableA a join TableB on ... join TableC on ... where (select count(*) from TableA where TableA.Field = Bla) > 100 

Хотя запросы занимают незаметное время, для запроса всего набора записей требуется значительное количество времени, которое может составлять 4-5 часов на сервере. Особенно, если есть много критериев, в конце проект прекратит выполнение импорта и отката.

Я попытался изменить «SELECT * FROM» на «SELECT TableA.ID FROM», но, похоже, он не имеет никакого эффекта. Есть ли лучший дизайн для улучшения производительности этого процесса?

Как создать временную таблицу (или более одного), которая хранит агрегированные результаты подзапросов, а затем индексирует это / с индексом покрытия.

Из вашего кода выше мы создадим группировку temp table на TableA.Field1 и включаем счетчик, а затем индекс в Field1, theCount. На SQL-сервере самым быстрым подходом было бы следующее:

 select * from TableA a join TableB on ... join TableC on ... join (select Field1 from #temp1 where theCount > 100) t on... 

Причина в том, что мы делаем тот же трюк дважды.

Во-первых, мы предварительно агрегируем в временную таблицу, что является простой операцией и очень просто для оптимизации SQL Server. Таким образом, мы взяли часть проблемы и решили оптимизированным образом.

Затем мы повторяем этот трюк, присоединяясь к подзапросу, помещая фильтр внутри подзапроса, так что соединение действует как фильтр.

Я бы предложил вам пакетные записи вместе (по 500 или около того за раз) и отправить их в сохраненный процесс, который может выполнять вычисления.

Используйте простые инструкции вместо объединений. Это тоже экономит. Эта ссылка также может помочь.

Хороший выбор – использование индексированного представления. http://msdn.microsoft.com/en-us/library/dd171921(SQL.100).aspx

  • Вставлять элементы из списка TVP через хранимую процедуру, только если запись не существует - медленная производительность
  • Как группировать таблицу, сохраняя при этом все значения столбцов в каждой группе в один столбец как значения, разделенные запятыми
  • Почему SqlConnection.Open работает медленно
  • Настройка SQL Server
  • Быстрый способ сравнения различий между упорядоченными записями SQL
  • cross apply xml query выполняет экспоненциально хуже, поскольку XML-документ растет
  • Создание оптимизированной таблицы Azure SQL для запросов
  • Необычная проблема с производительностью: общие выражения таблицы в встроенной пользовательской функции
  • Будет ли добавлен NONCLUSTERED INDEX, предложенный DTA, повысить производительность?
  • Должно ли мое мнение быть намного медленнее, чем мой сохраненный процесс?
  • Обработка очень большой таблицы в производительности SQL Server
  • Давайте будем гением компьютера.