本文和大家分享一下避免使用count(*)獲得表的記錄數,解決其延遲問題,為了提高SQL執行效率使用sysindexes.rows來快速的計算表的行數。
結果發現取出來的行數根本就不是實際表中的行數
就好比這樣
為了獲得表中的記錄數,一般都使用下面的SQL語句:
SELECT COUNT(*) FROM dbo.orders
但這條語句會執行全表掃描才能獲得行數。
下面的SQL語句不會執行全表掃描一樣可以獲得行數:
SELECT rows FROM sysindexes
WHERE id = OBJECT_ID('表名') AND indid < 2
網上很多優化文章都推薦這種做法,無可厚非,這種計算 sysindexes 中的rows,確實比計算實際表中的行數快。
但是由於像剛才那樣發生問題的情況不多所以很容易被人們所忽略其實sysindexes 是以延遲的方式更新,rows計數可能會不准確
下面就是我用兩種方法獲取同一個表的行數所返回的值
可以清楚的看到兩組返回值並不一致
不細心的人由此可鬧出不少笑話
接下來給出解決這種延遲問題的方法:
在查詢分析器裡面執行 DBCC UPDATEUSAGE(0, orders) with COUNT_ROWS
使用DBCC UPDATEUSAGE報告sysindexes中的頁數和行數錯誤並進行更正
0:表示當前數據庫,
orders:需要進行報告和更正的表
COUNT_ROWS:指定使用表或視圖中的行數的當前計數更新 row count 列
DBCC UPDATEUSAGE應用有很多,本文沒做深挖
感興趣的朋友可查閱更多相關資料
執行完畢後提示
---------------------------------------------------------------------
DBCC UPDATEUSAGE: 已更新表 orders的 sysindexes 行(索引 'PK_PND_ORDERS',分區 1):
行計數: 已從(7775)行更改為(7849)行。
DBCC 執行完畢。如果 DBCC 輸出了錯誤信息,請與系統管理員聯系。
---------------------------------------------------------------------
這時就及時更新了sysindexes使其和實際表中的行數達到一致。