четверг, 17 мая 2012 г.

Реактивный подсчет количества строк в таблице

Одной из самых что ни есть рядовых и часто встречающихся задач является подсчет количества строк в таблице. MS SQL Server предоставляет стандартное решение для такой задачи - старый добрый COUNT. Да, для таблиц с небольшим количеством записей использование COUNT как говорится - то, что доктор прописал. Однако если записей миллион или с десяток миллионов или еще больше? Посмотрим каковы будут результаты.
Для наглядности будем использовать для теста таблицу (назовем ее Ads) с количеством записей, например, больше 10 миллионов. Итак, приступим - первый стандартный вариант с использованием COUNT:

  1. select count(*) from Ads
* This source code was highlighted with Source Code Highlighter.

Взглянем на результаты:

- статистика:
SQL Server Execution Times:
CPU time = 1076 ms, elapsed time = 1174 ms.

- данные из плана выполнения:



То что мы видим не сильно впечатляет. Если выполнить предыдущий код с распараллеливанием - результаты конечно будут в разы лучше:

- статистика:
SQL Server Execution Times:
CPU time = 1997 ms, elapsed time = 149 ms.

- данные из плана выполнения:


но ведь можно еще быстрее! Для этого нам потребуется представление sys.dm_db_partition_stats. Собственно код:
  1. select sum(ps.row_count)
  2. from sys.dm_db_partition_stats ps
  3. where ps.object_id = object_id(N'Ads')
  4. and ps.index_id<2
* This source code was highlighted with Source Code Highlighter.

Результаты:

- статистика:
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 38 ms.

- данные из плана выполнения:


Результат превзошел все ожидания!
Теперь мы можем быстро считать количество записей в любой таблице!


Полезные ссылки:
- подробнее о представлении sys.dm_db_partition_stats можно почитать тут

3 комментария:

  1. Результат может не соответствовать ожиданиям...
    row_count
    bigint
    The _approximate_ number of rows in the partition.

    ОтветитьУдалить
    Ответы
    1. Спасибо за комментарий! Да, вы правы, если в спецификации так написано - значит были прецеденты :) За все время, сколько я использовал данный подход - результаты были правильными. Сразу скажу что в реальных проектах использовал всего один раз (где погрешность в точном количестве была не критичной), в остальных случаях для личных подсчетов, сбора информации и т.п.

      Удалить
    2. https://blogs.msdn.microsoft.com/martijnh/2010/07/15/sql-serverhow-to-quickly-retrieve-accurate-row-count-for-table/

      Удалить