首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 快速獲取表行數:sysindexes.rows 替代 COUNT(*) 實戰

     編輯:關於SqlServer

痛點

SELECT COUNT(*) FROM tableA 在千萬行大表上極慢(DELL 4400 測試:100萬行耗時 1 分鐘+)。聚簇索引首次執行同樣慢,後續雖快但大量增刪後又退化,且大表不適合建聚簇索引(嚴重拖慢增刪)。

核心原理

每個表在 sysindexes 系統表至少有一行記錄,rows 列**定時記錄表行數**:

列類型含義
idint表 ID(indid=0 或 255 時),否則為索引所屬表 ID
indidsmallint0=堆表,1=聚簇索引,>1=非聚簇索引,255=含 text/image 的表條目
rowsint基於 indid=0 和 1 的數據行數,indid>1 重復此值,indid=255 時為 0

無聚簇索引時 indid=0,有聚簇索引時 indid=1。

毫秒級查詢語句


SELECT rows 
FROM sysindexes 
WHERE id = OBJECT_ID('tablename') 
  AND indid IN (0, 1)

速度比 COUNT(*) **快數萬倍**,毫秒級完成。

關鍵限制:非實時、非精確

  • SQL Server **非實時更新** rows,而是定時更新(Checkpoint/統計更新時)
  • 實測誤差通常不大,適合**快速粗略估算**表大小

獲取精確值的兩種方案

方案一:強制同步統計


DBCC UPDATEUSAGE('DatabaseName', 'TableName') WITH ROW_COUNTS
-- 然後再查 sysindexes.rows

首次執行耗時大,效果等同聚簇索引表的 COUNT(*)。

方案二:建聚簇索引

聚簇索引表 COUNT(*) 走葉級掃描,極快。但**大表頻繁增刪不宜建聚簇索引**(頁分裂嚴重)。

決策矩陣

需求推薦方案代價
粗略估算、極速sysindexes.rows毫秒,非精確
精確、可接受秒級DBCC UPDATEUSAGE + sysindexes.rows首次同步慢,後續快
精確、高頻查詢、寫入少建聚簇索引 + COUNT(*)寫入性能犧牲
精確、高頻寫入應用層維護計數表 / 觸發器同步開發成本,寫入微增

現代替代(SQL Server 2008+)


-- DMV 方式,準確且快
SELECT SUM(p.rows) 
FROM sys.partitions p 
WHERE p.object_id = OBJECT_ID('tablename') 
  AND p.index_id IN (0, 1)

總結

sysindexes.rows 是「快速估算」神器;精確計數視業務權衡選擇 DBCC UPDATEUSAGE、聚簇索引或應用層計數表。**不要在大表高頻執行 COUNT(*) 無索引掃描**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved