問:我發現sysindexes索引表中的很多條目並不是我自己創建的。聽說它們並不是真正的索引,而是SQL Server查詢優化器自動創建的統計。怎樣才能識別哪些是真正的索引,哪些是SQL Server自動創建的統計呢?
答:按照默認設置,如果表中的某列沒有索引,則SQL Server會自動為該列創建統計。然後,查詢優化器評估該列中數據分布范圍的統計信息,以選擇一個更為有效的查詢處理方案。分辨自動創建的統計很簡單,在SQL Server 7.0和SQL Server 2000中,自動創建的統計的前綴為_WA_Sys。
您還可以使用INDEXPROPERTY()函數的IsAutoStatistics屬性來區分一個索引是真正的還是自動創建的統計,讓SQL Server優化器選擇需要創建的統計。您還可以為您管理的數據庫啟用“自動創建統計表”選項。
很多人忽略了下面的明顯的結論。自動創建統計的存在意味著某個真正的索引可能會從中受益。請考慮下列代碼的輸出:
USE tempdb
GO
IF OBJECTPROPERTY(OBJECT_ID('dbo.orders'), 'IsUserTable')=1
DROP TABLE dbo.orders
GO
SELECT * INTO tempdb..orders FROM northwind..orders
GO
SELECT * FROM tempdb..orders WHERE orderid = 10248
GO
SELECT * FROM tempdb..sysindexes WHERE id = object_id('orders')
AND name LIKE
'_wa_sys%'
GO
該代碼在tempdb中復制Northwind Orders表,選擇一行,然後檢查SQL Server是否添加了一個統計。很顯然,該表沒有OrderId列的索引,所以SQL Server自動創建了名為_WA_Sys_OrderID_58D1301D 的統計。OrderId列統計表的存在表明Northwind Orders表將得益於附加的索引。
以下查詢顯示了為數據庫中每個用戶表自動創建的統計的數量,該數據庫至少有一個自動創建的統計。
SELECT
object_name(id) TableName
,count(*) NumberOfAutoStats
FROM
sysindexes
WHERE
OBJECTPROPERTY(id, N'IsUserTable') = 1
AND INDEXPROPERTY ( id , name , 'IsAutoStatistics' ) = 1
GROUP BY
object_name(id)
ORDER BY
count(*) DESC
並不是所有的統計都可被真正的索引所替代。在某些情況下,SQL Server會為一個表自動創建超過50個統計。很明顯,這些表的索引策略很差勁。對表及自動創建的與之相關聯的統計的快速記數可以幫助您確定哪些表需要索引。
―Microsoft SQL Server開發團隊