как эффективно вернуть количество записей в SQL? - PullRequest
1 голос
/ 06 сентября 2010

Я использую SQL Server 2008 Enterprise на Windows Server 2008 Enterprise. Я использую следующий код, чтобы вернуть часть данных для запроса для реализации подкачки (т. Е. Страницы вверх / вниз, чтобы показать часть результатов на каждой странице, например, подкачки результатов поиска Google) в моем веб-приложении (я использую pageCount в качестве числа результатов, показанных на каждой странице, и startPos в качестве начального номера результата). Например, pageCount 10 означает 10 результатов для каждой страницы, startPos = 0 означает первую страницу, startPos = 1 означает 2-ю страницу и т. Д.

Мой вопрос заключается в том, как эффективно получить общее количество результатов в моем сценарии? Моя главная проблема заключается в том, как реализовать пейджинг (т. Е. Коснуться только части результата) и одновременно получить общее количество результатов?

SELECT *
 FROM   (SELECT
    t.foo, t.goo, ROW_NUMBER() OVER (order by t.zoo DESC ) AS rowNum
   FROM
    dbo.mycorp  t

   WHERE
    (t.foo LIKE '%'+@search+'%'
    or t.foo  LIKE '%'+@search+'%'
    )
    ) tt
    WHERE  tt.rowNum between @startPos and  @pageCount + @startPos-1

спасибо заранее, George

Ответы [ 2 ]

3 голосов
/ 06 сентября 2010

Это будет означать избыточный столбец с одинаковым значением для каждой строки:

WITH cte AS (
    SELECT t.foo, 
           t.goo, 
           ROW_NUMBER() OVER (ORDER BY t.zoo DESC ) AS rowNum,
           (SELECT COUNT(*)
              FROM dbo.mycorp
             WHERE t.foo LIKE '%'+@search+'%'
                OR t.foo  LIKE '%'+@search+'%') AS total_count
      FROM dbo.mycorp  t
     WHERE t.foo LIKE '%'+@search+'%'
        OR t.foo  LIKE '%'+@search+'%')
SELECT c.foo,
       c.goo,
       c.total_count
  FROM cte c
 WHERE c.rowNum BETWEEN @startPos 
                    AND @pageCount + @startPos-1

Более эффективным средством поиска текста является использование функциональности полнотекстового поиска (FTS) SQL Server .

1 голос
/ 06 сентября 2010

Я бы подумал об использовании нескольких наборов записей, если ваша технология доступа к данным поддерживает это (я знаю, что ADO.NET поддерживает это).

Включите следующее после вашего запроса

SELECT COUNT(*) AS TotalRecordCount
 FROM   dbo.mycorp  t 
   WHERE 
    (t.foo LIKE '%'+@search+'%' 
    or t.foo  LIKE '%'+@search+'%' 
    ) 
    ) tt

На вашем уровне доступа к данным вам нужно будет переключиться на следующий набор записей после обработки результатов поиска, чтобы получить общее количество. При использовании ADO.NET для этого потребуется вызвать dataReader.NextResult ().

Самое главное - это измерить производительность. Я обнаружил, что в некоторых случаях использование отдельного оператора выбора вместо подзапроса может привести к более высокой производительности, поскольку оптимизатор запросов может лучше оптимизировать запрос. В любом случае вам понадобится подходящая индексация в столбце поиска.

...