非常に近い概算(実行中のトランザクションを無視)は次のようになります:
SELECT SUM(p.rows) FROM sys.partitions AS p
INNER JOIN sys.tables AS t
ON p.[object_id] = t.[object_id]
INNER JOIN sys.schemas AS s
ON s.[schema_id] = t.[schema_id]
WHERE t.name = N'myTable'
AND s.name = N'dbo'
AND p.index_id IN (0,1);
これにより、COUNT(*)
よりもはるかに高速に返されます。 、そしてテーブルが十分に速く変化している場合、それは実際にはそれほど正確ではありません-COUNTを開始したとき(およびロックが取得されたとき)とテーブルが返されたとき(ロックが解放されて待機中のすべての書き込みトランザクション)の間にテーブルが変更された場合テーブルへの書き込みが許可されました)、それははるかに価値がありますか?そうは思いません。
カウントしたいテーブルのサブセットがある場合(たとえば、WHERE some_column IS NULL
)、その列にフィルター処理されたインデックスを作成し、それが例外であるかルールであるかに応じて、where句をいずれかの方法で構造化できます(したがって、小さいセットでフィルター処理されたインデックスを作成します)。したがって、次の2つのインデックスのいずれか:
CREATE INDEX IAmTheException ON dbo.table(some_column)
WHERE some_column IS NULL;
CREATE INDEX IAmTheRule ON dbo.table(some_column)
WHERE some_column IS NOT NULL;
次に、次を使用して同様の方法でカウントを取得できます:
SELECT SUM(p.rows) FROM sys.partitions AS p
INNER JOIN sys.tables AS t
ON p.[object_id] = t.[object_id]
INNER JOIN sys.schemas AS s
ON s.[schema_id] = t.[schema_id]
INNER JOIN sys.indexes AS i
ON p.index_id = i.index_id
WHERE t.name = N'myTable'
AND s.name = N'dbo'
AND i.name = N'IAmTheException' -- or N'IAmTheRule'
AND p.index_id IN (0,1);
反対のことを知りたい場合は、上記の最初のクエリから差し引くだけです。