Perkiraan yang sangat mendekati (mengabaikan setiap transaksi dalam penerbangan) adalah:
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);
Ini akan kembali jauh, jauh lebih cepat daripada COUNT(*)
, dan jika tabel Anda berubah cukup cepat, itu tidak benar-benar kurang akurat - jika tabel Anda telah berubah antara saat Anda memulai COUNT Anda (dan kunci diambil) dan ketika dikembalikan (ketika kunci dilepaskan dan semua transaksi tulis menunggu sekarang diizinkan untuk menulis ke meja), apakah itu jauh lebih berharga? Saya rasa tidak.
Jika Anda memiliki beberapa subset dari tabel yang ingin Anda hitung (misalnya, WHERE some_column IS NULL
), Anda bisa membuat indeks yang difilter pada kolom itu, dan menyusun klausa where dengan satu atau lain cara, tergantung pada apakah itu pengecualian atau aturan (jadi buat indeks yang difilter pada set yang lebih kecil). Jadi salah satu dari dua indeks ini:
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;
Kemudian Anda bisa mendapatkan hitungan dengan cara yang sama menggunakan:
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);
Dan jika Anda ingin mengetahui kebalikannya, Anda tinggal mengurangkan dari kueri pertama di atas.