Быстрый способ оценить ряды по критериям - PullRequest
0 голосов
/ 18 июня 2011

Я видел несколько постов, подробно описывающих быстрые способы «оценить» количество строк в данной таблице SQL без использования COUNT(*).Однако ни один из них, по-видимому, не решает проблему, если вам нужно оценить количество строк, которые удовлетворяют заданному критерию .Я пытаюсь найти способ оценки количества строк, которые удовлетворяют заданным критериям, но информация для этих критериев разбросана по двум или трем таблицам.Конечно, подойдет SELECT COUNT(*) с подсказкой NOLOCK и несколькими объединениями, и я могу позволить себе занижать или переоценивать общее количество записей.Проблема в том, что этот вид запроса будет выполняться каждые 5-10 минут или около того, и, поскольку мне не нужно фактическое число - только оценка, - я бы хотел компромисс между точностью и скоростью.

Решение, если оно есть, может зависеть от SQL Server.Фактически он должен быть совместим с SQL Server 2005. Любые подсказки?

Ответы [ 2 ]

1 голос
/ 19 июня 2011

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

Но нет способа сделать это для заданного набора критериев в предложении WHERE - либо вам придется вести подсчет для каждого набора критериев и значений, либо вам придется использовать черную магию, чтобы выяснить это , Единственное место, где SQL Server хранит что-то, что могло бы пойти в этом направлении, - это статистика по индексам. Они будут иметь определенную информацию о том, какие значения встречаются в индексе как часто, но я, честно говоря, понятия не имею, можете ли вы (и как) использовать эту информацию в статистике в своих собственных запросах ......

Если вы действительно должны знать количество строк, соответствующих определенным критериям, вам необходимо выполнить подсчет некоторого вида - либо SELECT COUNT(*) FROM dbo.YourTable WHERE (yourcriteria), либо что-то еще.

Что-то еще может быть что-то вроде этого:

  • оберните ваш оператор SELECT в CTE (общее табличное выражение)
  • определяет ROW_NUMBER() в том CTE, упорядочивая ваши данные по некоторому столбцу (или множеству столбцов)
  • добавить секунду ROW_NUMBER() к тому CTE, который упорядочивает ваши данные по тому же столбцу (или столбцам) - но в противоположном направлении (DESC против ASC)

Примерно так:

;WITH YourDataCTE AS
(
   SELECT (list of columns you need),
      ROW_NUMBER() OVER(ORDER BY <your column>) AS 'RowNum',
      ROW_NUMBER() OVER(ORDER BY <your column> DESC) AS 'RowNum2'
   FROM
      dbo.YourTable
   WHERE
      <your conditions here>
)
SELECT * 
FROM YourDataCTE

При этом вы получите следующий эффект:

  • ваша первая строка в наборе результатов будет содержать ваши обычные столбцы данных
  • первый ROW_NUMBER() будет содержать значение 1
  • второй ROW_NUMBER() будет содержать общее количество строк, соответствующих заданным критериям

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

0 голосов
/ 18 июня 2011

Возможные решения:

  • Если число считается большим по сравнению с общим числом строк в таблице, то добавление индексов, которые охватывают условие where, поможет и запрос будет очень быстрым.

  • Если число результатов близко к общему количеству строк в таблице, индексы мало чем помогут. Вы можете реализовать триггер, который будет поддерживать «таблицу условного подсчета». Таким образом, всякий раз, когда добавляется условие соответствия строки, вы увеличиваете значение в таблице, а когда строка удаляется, вы уменьшаете значение. Таким образом, вы будете запрашивать эту маленькую «сводную таблицу подсчета».

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