Я не за компьютером, поэтому я не смогу добавить код до тех пор, пока вы не предоставите мне достаточно информации, чтобы дать мне хорошее представление.
Во-первых, оптимизатор никогда не сможетиспользовать индекс для предотвращения сортировки при заказе с помощью оператора CASE.Тем не менее, есть много причин, по которым ваш запрос может быть медленным;Вы должны удалить эту логику, а затем протестировать производительность, чтобы понять, является ли это виновником.
Исходя из ограниченной информации, я предлагаю обновить ваш proc: 1. Использовать динамический SQL для построения вашей временной таблицы, так как высделали, но без заявления CASE.
В этот динамический SQL ^^^ должен быть включен код для построения кластеризованного индекса с @columnName в качестве ключа кластера и использованием @sortDir для определения порядка сортировки индекса.
Теперь у вас естьвременная таблица правильно проиндексирована на основе предоставленных пользователем параметров.
Добавьте второй динамический оператор SQL, который выполняет SELECT * FROM #temp ... Вы снова будете использовать @columnName и @sortOrder для построения SARGable ORDER BY (который будет использовать индекс из шага # 1).
Тестирование с различными параметрами, всегда отслеживая план фактического выполнения для дальнейшей настройки ваших индексов.
Надеюсь, это поможет. Я добавлю демонстрациюкод немного позже, если вам нужно.
Обновлено 22.02.2009, чтобы включить примеры:
Вот хранимый процесс, который делает то, что я описываю (примечаниекомментарии) -
SET NOCOUNT ON;
USE tempdb
GO
IF OBJECT_ID('dbo.DynamicSortProc','P') IS NOT NULL DROP PROC dbo.DynamicSortProc;
GO
CREATE PROC dbo.DynamicSortProc @sortby NVARCHAR(100), @sortorder NVARCHAR(4)
AS
BEGIN
-- 1. Populate the temp table (sample data)
IF OBJECT_ID('##tmp','U') IS NOT NULL DROP TABLE ##tmp;
SELECT SomeId = IDENTITY(INT,1,1), ColA, ColB
INTO ##tmp
FROM (VALUES(1,3),(6,5),(2,8),(5,5),(2,6),(5,1)) AS f(ColA,ColB);
-- NOTE: On SQL 2014+ SELECT INTO is often faster than the standard create+insert
;
-- 2. Setup @sortby
SET @sortby = QUOTENAME(@sortby)+' '+CASE @sortorder WHEN 'DESC' THEN 'DESC' ELSE '' END;
-- 3. Set up the Dynamic SQL
DECLARE @createIndex NVARCHAR(4000) = 'CREATE CLUSTERED INDEX x ON ##tmp ('+@sortby+') ';
DECLARE @executeQuery NVARCHAR(4000) = 'SELECT t.* FROM ##tmp AS t ORDER BY '+@sortby;
-- 4. Execute the queries
EXEC sys.sp_executesql @createIndex;
EXEC sys.sp_executesql @executeQuery;
END
GO
Вы можете выполнить тестирование следующим образом:
EXEC dbo.DynamicSortProc 'ColA', 'ASC';
EXEC dbo.DynamicSortProc 'ColA', 'DESC';
EXEC dbo.DynamicSortProc 'ColB', 'ASC';
EXEC dbo.DynamicSortProc 'ColB', 'DESC';
В каждом случае они сортируются, как ожидалось, и в выходном запросе сортировка отсутствует.