標籤:group 影響 dex sts html tail 檔案 沒有 microsoft
參考原文:http://www.cnblogs.com/tjy9999/p/4494662.html
1. 非叢集索引
SET STATISTICS io ON SET STATISTICS time ON -- 1. 沒有索引(logical reads 568)SELECT FirstName, LastName FROM dbo.Contact WHERE LastName LIKE ‘S%‘ -- 建立非叢集索引IF EXISTS (SELECT * FROM sys.indexes WHERE OBJECT_ID = OBJECT_ID(‘Person.Contact‘) AND name = ‘FullName‘) DROP INDEX Person.Contact.FullName; CREATE NONCLUSTERED INDEX FullName ON Person.Contact( LastName, FirstName ); GO -- 2. 完全覆蓋的查詢(logical reads 14)SELECT FirstName, LastName FROM dbo.Contact WHERE LastName LIKE ‘S%‘ -- 3. 非完全覆蓋的查詢(logical reads 568) SQL Server覺得使用索引尋找,比直接掃描還要做更多的工作,因此沒有使用索引.SELECT * FROM dbo.Contact WHERE LastName LIKE ‘S%‘ -- 4. 非完全覆蓋的查詢(logical reads 111) 改變where條件,從而減少查詢結果的範圍,增加使用索引的好處,SQL Server使用索引尋找來縮短查詢時間.SELECT * FROM dbo.Contacts WHERE LastName LIKE ‘Ste%‘
2. 叢集索引
非叢集索引是獨立的對象,有自己的儲存空間,而叢集索引和表是同一個對象。建立一個叢集索引的時候,SQL Server用key對錶進行排序,並且在修改資料的時候維護排序。因此當叢集索引的鍵是訂單號,那麼同一個訂單的資訊在表中的順序是連續的。每張表只能有一個叢集索引,因為表只能按照一個順序來排列。如果一張表上沒有叢集索引,表也被叫做堆,因此表分為兩種類型:叢集索引表和堆表。
CREATE CLUSTERED INDEX IX_SalesOrderDetail ON dbo.SalesOrderDetail (SalesOrderID, SalesOrderDetailID) GO -- 1. 堆表查詢(logical reads 1495) & 叢集索引表查詢(logical reads 3)SELECT * FROM SalesOrderDetailWHERE SalesOrderID = 43671 AND SalesOrderDetailID = 120-- 2. 堆表查詢(logical reads 1495) & 叢集索引表查詢(logical reads 1513)-- ProductID列不是叢集索引的鍵。兩種表都進行了表掃描。因為包含了叢集索引,叢集索引表更大,所以掃描了更多的次數。SELECT * FROM SalesOrderDetail WHERE ProductID = 755
3. 頁和區
SQL Server在建立資料庫的時候,即指定資料檔案的存放位置。SQL Server讀取的不是行,讀取的單位是一頁或者更多頁。頁是最小的IO單元,每頁的大小是8K。一個分區包含8個連續的頁。每一行的大小=所有列的大小+行的頭部資訊。
4. 包含列
- 表中的每一行在索引中總是有一個入口(這條規則有一個意外,在後面的層級中我們會講到)。這些入口總是用索引鍵排序。
- 在叢集索引中,索引的入口就是表的實際行。
- 在非叢集索引中,入口和資料行是分開的,索引由索引鍵列和標籤組成,標籤是索引鍵列到表資料行的映射。
那些經常出現在select中的,而不是where子句中的列,最好放在包含列中。索引列不會影響索引入口的排序,只會更新索引的入口,但是不需要移動。
CREATE NONCLUSTERED INDEX FK_ProductID_ ModifiedDate ON Sales.SalesOrderDetail (ProductID, ModifiedDate) INCLUDE (OrderQty, UnitPrice, LineTotal) -- 該查詢在包含列的非叢集索引下速度更快SELECT ProductID , ModifiedDate , SUM(OrderQty) AS ‘No of Items‘ , AVG(UnitPrice) ‘Avg Price‘ , SUM(LineTotal) ‘Total Value‘ FROM Sales.SalesOrderDetail WHERE ProductID = 888 GROUP BY ProductID ,ModifiedDate ;
5. 標籤
據庫中的每一行,在任何時間,都可以用三個數字來標識:檔案號-頁號-行號。這三個數位複合標識叫做rowid,通常叫做RID。因此檔案1的77頁的12行,RID會顯示成1:77:12。
一個堆表的非叢集索引:RID為基礎的標籤
通常來講,一個堆表的行是不會移動的,一旦他們被插入一頁,他們會保持在這頁中。更加精準的說法是:在堆表中的行很少移動,當他們移動的時候,在舊的位置上會留下新的地址。因為堆表的行不會移動,在堆表中RID永久的標識每一行。不僅值是永久的,而且物理位置也是永久的。索引中每一行的標籤都是很有效,直接指向對應的資料行。
叢集索引的非叢集索引:鍵為基礎的標籤
叢集索引表的行是可以移動的,在修改資料或者是維護索引的時候可能會分配到另外一頁。當叢集索引的一行被移動到新頁的時候,它只是被移動,而叢集索引的索引值沒有改變。因此可以用索引索引值作為行的標籤。叢集索引的鍵應該滿足三個條件:短小、靜態,並且唯一。叢集索引索引值的改變,會導致每一個非叢集索引中對應行的入口發生更新操作。因此,如果一張表有n個非叢集索引,一次索引鍵的更新,會變成n+1次的更新。
非叢集索引的入口由查詢鍵列、包含列、標籤組成。標籤的值既可以是RID,也可以是叢集索引的鍵,這依賴於表是堆表還是叢集索引表。為表選擇最好的叢集索引需要你依據三條規則,確保索引鍵是一個好的標籤。
sqlserver 索引