Изменение дизайна запросов для повышения производительности
Это больше похоже на вопрос дизайна, но также связан с оптимизацией SQL.
Мой проект должен импортировать большое количество записей в базу данных (более 100 тыс. Записей). В то же время у проекта есть логика для проверки каждой записи, чтобы убедиться, что она соответствует критериям, которые можно настроить. Затем он будет отмечать запись как предупреждение или предупреждение в базе данных. Проверка вставки и предупреждения выполняется в рамках одного процесса импорта.
Для каждого критерия он должен запрашивать базу данных. Запрос должен объединяться в две другие таблицы и иногда добавлять дополнительный вложенный запрос внутри условий, таких как
- Производительность кластеризованных и некластеризованных индексов
- SQL - улучшает производительность NOT EXISTS
- Время выполнения LINQ to SQL на 50 раз больше, чем SSMS SQL
- Насколько значительным является ограничение производительности при использовании Int64 / bigint вместо Int32 / int в приложении C # 4 / T-SQL2008 под 32-разрядной Windows XP?
- Присоединение к производительности CTE
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», но, похоже, он не имеет никакого эффекта. Есть ли лучший дизайн для улучшения производительности этого процесса?
- Изменение триггера SQL для работы, когда вставленная таблица содержит более одной строки
- Как дорого выбрать отдельный * запрос
- Рассчитанные поля, которые улучшают производительность, но должны поддерживаться (EF)
- план выполнения запроса: отсутствует индекс
- SQL Script в VM занимает много времени для выполнения
- SqlDataReader с запросом с объединениями
- MongoDB против SQL Server для хранения рекурсивных деревьев данных
- Почему UDF намного медленнее, чем подзапрос?
Как создать временную таблицу (или более одного), которая хранит агрегированные результаты подзапросов, а затем индексирует это / с индексом покрытия.
Из вашего кода выше мы создадим группировку 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