Как оптимизировать счетчики строк sproc, которые занимают слишком много времени? - PullRequest
0 голосов
/ 27 июля 2011

В SQL Server 2008R2 sproc у меня есть следующий код для вычисления общего количества записей, возвращаемых динамическим запросом:

        -- count the actual number of results
        DECLARE @rowcount TABLE (Value int);
        INSERT INTO @rowcount
        EXEC('SELECT COUNT(*) ' + @sqlBody);
        SELECT @varcharActualNumResults = VALUE FROM @rowcount;

Динамический запрос разбит на три части: @sqlTop,@sqlBody и @ sqlBottom.

Я хочу знать, сколько записей на самом деле возвращается @sqlBody, но фактическим выполнением является сцепленный @sqlTop + @sqlBody + @ sqlBottom.

Проблема в том, что приведенный выше запрос занимает 24136 мс (примерно 24 секунды), где фактическое количество записей составляет около 18 000.

Другая проблема возникает, когда я хочу получить количество строк для всего запроса:

         EXEC (@sqlTop + @sqlBody + @sqlBottom)
         SET @NumberOfResultsReturned = @@ROWCOUNT;

Это выполнение занимает примерно две секунды.

Вот пример запроса:

SELECT TOP(10) Title
FROM ItemData 
WHERE  ( 
           FREETEXT(Title, '"windshield"')  
           OR 
           (   [Title] LIKE '%mazda 6%' )  
       )   
AND  ( WebsiteID=1 )  
ORDER BY DateAdded DESC 

@ sqlBody содержит все, что находится между FROM и ORDER BY.

Как это можно оптимизировать?

ОБНОВЛЕНИЕ

В моем sproc я определил свою временную таблицу, а затем попытался заполнить ее с помощью команды EXEC.Однако в командной строке EXEC я получаю сообщение об ошибке, указывающее, что временная таблица должна быть определена:

DECLARE @Temp_Results TABLE (ItemListID BIGINT, Title VARCHAR(255) )
EXEC ('INSERT INTO @Temp_Results (ItemListID, Title) (' + @sqlTop + @sqlBody + ')')

Если я возьму команду exec и выполню SQL, она будет работать нормально.Как я могу обойти это?

Ответы [ 2 ]

1 голос
/ 27 июля 2011

Из вашего обновления вы создали переменную таблицы , а не временную таблицу . Табличные переменные (как и все остальные переменные) недоступны во вложенных областях. Временные таблицы есть. Вы можете попробовать:

CREATE TABLE #Temp_Results (ItemListID BIGINT, Title VARCHAR(255) )
EXEC ('INSERT INTO #Temp_Results (ItemListID, Title) (' + @sqlTop + @sqlBody + ')')
0 голосов
/ 27 июля 2011

Теперь я понимаю вашу проблему и считаю, что лучше всего не использовать динамический запрос. Однако, если вам нужно использовать динамический запрос, вот несколько способов ускорить его.

  1. Убедитесь, что все элементы в каталоге where имеют индексы.

  2. Добавьте ваш подсчет в EXEC, чтобы счетчик строк возвращался одним вызовом exec. Например, в вашем динамическом запросе поместите результаты сокращения во временную таблицу и сосчитайте эту таблицу, затем выберите из этой таблицы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...