2013-06-10 4 views
1

У меня довольно сложное представление, в котором содержится около 100 подзапросов.Оптимизация генерации запросов SQL Server

Простое утверждение, как:

SELECT * FROM MyView 

займет 2 секунды, чтобы сгенерировать план и выполнить query.Subsequent выбирает, когда план кэшируется займет менее 1 мс для выполнения.

Эта ситуация была бы в порядке, если бы у меня было всего несколько запросов - производительность ударяется только один раз. Проблема в том, что наш ORM генерирует запросы подкачки с параметрами с помощью CTE. Изменение значений параметров (страниц) вызывает перерасчет плана запроса - в этом случае это, к сожалению, занимает около 4 секунд!

Давайте добавим фильтрацию, сортировку, и вы получите представление о том, что происходит ..

Что я могу сделать, чтобы сократить времена создания плана запроса или сделать их меньше или оптимизировать это каким-либо другим способом?

@MartinSmith «SQL Server не создает план для каждого значения параметра, за исключением, если текст как-то изменилось»

У меня есть запрос, как это (я поместил звезды здесь вместо более 120 полей список):

DECLARE @low int = 20; 
DECLARE @high int = 300; 

WITH __actualSet 
AS (
SELECT * 
    ,ROW_NUMBER() OVER (
     ORDER BY CURRENT_TIMESTAMP 
     ) AS __rowcnt 
FROM (
    SELECT TOP 5000 * 
    FROM [dbo].[Project] [LPA_L1] 
    ORDER BY [LPA_L1].[CreatedOn] ASC 
    ) AS _tmpSet 
) 
SELECT * 
FROM __actualSet 
WHERE [__rowcnt] > @low 
AND [__rowcnt] <= @high 
ORDER BY [__rowcnt] ASC 

Первый раз, когда я выполняю этот запрос ~ 4s. Второй раз ~ 1 мс. Когда я меняю значения параметра - снова 4 с. Может быть, я что-то неправильно истолковываю?

+0

Перепишите вид не использовать 100 подзапросы? Хотя, если единственное изменение - значения '@ parameter', это не должно вызывать перекомпиляции. –

+0

Я не могу переписать представление, чтобы не использовать 100 подзапросов, однако я попытаюсь использовать проекцию, чтобы сократить количество столбцов, запрошенных каждый раз. Это работает в основном одинаково, но все же генерация плана выполнения для каждого значения параметра сумасшедшая. – kubal5003

+0

SQL Server не создает план для каждого значения параметра, кроме как если бы текст каким-то образом изменился. –

ответ

1

Для тестирования в SSMS и повторно использовать один и тот же план для различных значений, которые необходимо параметризировать запрос и выполнить его с sp_executesql

DECLARE @low int = 20; 
DECLARE @high int = 300; 

EXEC sp_executesql N' 
WITH __actualSet 
AS (
SELECT * 
    ,ROW_NUMBER() OVER (
     ORDER BY CURRENT_TIMESTAMP 
     ) AS __rowcnt 
FROM (
    SELECT TOP 5000 * 
    FROM [dbo].[Project] [LPA_L1] 
    ORDER BY [LPA_L1].[CreatedOn] ASC 
    ) AS _tmpSet 
) 
SELECT * 
FROM __actualSet 
WHERE [__rowcnt] > @low 
AND [__rowcnt] <= @high 
ORDER BY [__rowcnt] ASC 

', N'@low INT, @high INT', @low = @low, @high = @high 
+0

Спасибо за это. Это работает как шарм! Менее 1 мс для любых значений параметров! – kubal5003

Смежные вопросы