Какая была самая крутая оптимизация SQL для медленного запроса?
Просто говорю с моим коллегой. Он шел с прыжком на своем пути, по дороге к кофеварке.
Я спросил его: "Что с" ройной "прогулкой?", Он ответил: "Я только что сократил двухчасовой запрос до 40 секунд! Это так здорово".
Он изменил хранимую процедуру, в которой использовались курсоры, и представил временную таблицу, которая была реорганизована из исходного набора данных - я скоро отправлю ему электронное письмо, чтобы получить больше информации о фактической реализации.
Но в конечном итоге он гудел.
Вопрос в том, что за SQL, который запал вам в голову и заставил вас гудеть, оптимизируя медленные запросы?
15 ответов
Я должен сказать, когда я узнал, как создавать и использовать закрытые индексы. Теперь, это было повышение производительности.
Использование SQL BULKIMPORT позволяет сократить несколько часов унаследованного кода INSERT до менее чем одной минуты.
Всегда приятно брать плохо написанный, загруженный курсором запрос и исключать курсоры, сокращать код вдвое и многократно повышать производительность.
Некоторые из лучших улучшений ясны (и часто также приводят к хорошему повышению производительности).
Эй на iphone, который использует sqlite, я сразу сократил время обработки базы данных с 40 секунд до 2 секунд с использованием эксклюзивных транзакций записи... я был очень счастлив сделать это
так как это был мой первый опыт использования sql на встроенном устройстве - он сильно отличался от обычных вещей, связанных с сервером (индексов, нормализаций и т. д.)
--- что касается серверов, индексы являются настоящим благословением. Кроме того, если вы немного постараетесь и избавитесь от как можно большего числа нулей в своей таблице, вы будете удивлены приростом производительности - не многие разработчики фокусируются на пустых значениях, они обычно используют индексы и другие документированные вещи.
несколько других менее эксплуатируемых способов - использование xml для обработки нескольких пакетных вставок / обновлений / удалений за один раз вместо выполнения одной вставки за раз - в SQL 2005 это может быть очень круто
У меня был запрос, который был изначально написан для SQL Server 6.5, который не поддерживал синтаксис соединения SQL 92, т.е.
select foo.baz
from foo
left outer join bar
on foo.a = bar.a
вместо этого было написано как
select foo.baz
from foo, bar
where foo.a *= bar.a
Запрос был на некоторое время, и соответствующие данные были собраны, чтобы сделать запрос слишком медленным, около 90 секунд, чтобы его завершить. К тому времени, когда возникла эта проблема, мы обновились до SQL Server 7.
После работы с индексами и прочим пасхальным кодированием я изменил синтаксис соединения, чтобы он соответствовал SQL 92. Время запроса сократилось до 3 секунд.
Я не думаю, что когда-нибудь снова у меня будет такое чувство. Я был героем.
Извините, я не склонен получать ажиотаж от подобных вещей, но большинство ситуаций были довольно простыми, отслеживая производительность запросов и добавляя индексы, чтобы ускорить их.
Теперь, увеличив скорость "реального" кода, который я написал, изменив структуры данных и алгоритмы в классе, я получаю кайф (и репутацию профессионала, который исправляет производительность на работе).
Это все об индексах. И избегать глупостей, которые делают их бесполезными.
Изменение порядка условий внутри предложения WHERE, чтобы оно сначала отфильтровывало наиболее различающее условие (при этом удаляются индексы из недискриминационных столбцов, таких как пол).
Когда-то я работал над системой CICS/DB2, написанной на языке COBOL. Многие наши запросы выполняли полное (и медленное) сканирование таблицы, хотя у нас были все правильные индексы и WHERE
статьи.
Оказалось (и я могу иметь это задом наперед, прошло 15 лет), что проблема заключалась в том, что мы использовали PIC S9(n) COMP
в WORKING STORAGE
для параметров запроса, но хотел DB2 PIC S9(n) COMP-3
, Используя неверный тип данных, DB2 должна была выполнить полное сканирование таблицы, чтобы преобразовать значения в базе данных в значение, которое мы передавали. Мы изменили наши определения переменных, и запросы теперь могли использовать индексы, что резко улучшил нашу производительность.
Я ответил на этот вопрос на предыдущем вопросе ( "Наибольшее улучшение производительности, которое вы имели с наименьшим изменением?"), Однако, это такое простое улучшение, но такое, которое так часто пропускают, что оно повторяется:
У меня было теплое свечение после того, как я смог использовать запрос кросс-таблицы, чтобы отбросить кучу (технический термин) обработки и поиска...
Обычно это простые вещи, такие как добавление индексов или получение только тех данных, которые вам нужны, но когда вы обнаружите проблему, которая соответствует ответу, который вы видели раньше... хорошие времена!
Ну, у нас была похожая вещь, когда у нас был медленный запрос на сайте Open Freeway. Ответ был не столько в оптимизации запроса, сколько в оптимизации сервера, на котором он был. Мы увеличили лимит и размер кэша, чтобы сервер не выполнял запрос так часто.
Это значительно увеличило скорость системы и в конечном итоге сделало клиента счастливым!:)
Не совсем такого уровня, как оригинальные навыки оптимизации постов, но это определенно заставило нас кайфовать!
(Половина темы)
Я переписал хранимую процедуру из 3000 строк в LINQ2SQL/C#. Хранимая процедура манипулировала большим количеством данных между кучей неиндексированных временных таблиц. Версия LINQ2SQL считала данные в пару словарей и ILookups, а затем я соединил данные вручную с помощью старого старого кода C#.
Хранимая процедура заняла около 20 секунд, а версия LINQ2SQL / C# заняла 0,2 секунды.
Разделение одной смехотворно длинной хранимой процедуры, которая выполняла большую часть "если это после 5 часов вечера, верните этот бит sql" и на выполнение которой ушло более 20 секунд, на набор хранимых процедур, которые были вызваны одним управляющим sp и получил время до ответов за секунду.
Одно слово, динамические запросы
Если вы работаете с большим количеством параметров, вы можете исключить их из строки SQL. Это ускорило мои запросы резко и с достаточной легкостью.
Create PROCEDURE dbo.qryDynamic
(
@txtParameter1 nvarchar(255),
@txtParameter2 nvarchar(255),
AS
SELECT qry_DataFromAView.*
FROM qry_DataFromAView
BEGIN
DECLARE @SQL nvarchar(2500)
DECLARE @txtJoin nvarchar(50)
Set @txtJoin = ' Where '
SET @SQL = 'SELECT qry_DataFromAView.*
FROM qry_DataFromAView'
IF @txtParameter1 is not null
Begin
SET @SQL=@SQL + @txtJoin + ' Field1 LIKE N''%'' + @dynParameter1 + N''%'') '
Set @txtJoin = ' And '
end
IF @txtParameter2 is not null
Begin
SET @SQL=@SQL + @txtJoin + ' Field2 LIKE N''%'' + @dynParameter2 + N''%'') '
Set @txtJoin = ' And '
end
SET @SQL=@SQL + ' ORDER BY Field2'
Exec sp_executesql @SQL, N'@dynParameter1 nvarchar(255), @dynParameter2 nvarchar(255)', @dynParameter1 = @txtParameter1 ,@dynParameter2 = @txtParameter2
END
GO