通過前面二篇文章我們基本學會了如何結合執行計划分析出某Sql語句的性能問題,既然有性能問題的地方已經找到了,接下來就是如何優化查詢來提高查詢性能,而優化查詢最重要的武器就是創建索引,這篇文章就來總結如何創建索引來提高查詢速度,主要從以下幾個方面來總結。
- 了解索引
- 創建索引的語法
- 結合實例演示如何創建索引
了解索引
1,索引是什么?
在Sql Server中,索引是一種增強式的存在,這表示即使沒有索引,Sql Server的功能並不會受到影響。索引是對數據庫表中一列或多列的值進行排序的一種結構(B樹),使用索引可快速訪問數據庫表中的特定信息。
2,為什么要使用索引?
就是提高查詢性能。
3,有哪些索引?
主要分為聚集索引(CLUSTERED INDEX)和非聚集索引(NONCLUSTERED INDEX)兩種,聚集索引指的是一列或多列的物理順序和邏輯順序是一致的,一個數據庫表只能有一個聚集索引,我們通常將主鍵(一般為自增int型)設為聚集索引。而非聚集索引則可以有多個,而且非聚集索引並不會改變數據庫表的物理結構。
創建索引的語法
1,創建索引,sql語法如下。
-- 建立索引 IF NOT EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('Sales.Orders') AND name='idx_nc_orderdate') CREATE NONCLUSTERED INDEX idx_nc_orderdate ON Sales.Orders(orderdate); GO
2,刪除索引,sql語法如下。
-- 刪除索引 IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('Sales.Orders') AND name='idx_nc_orderdate') DROP INDEX idx_nc_orderdate ON Sales.Orders; GO
結合實例演示如何創建索引
表結構如下:
現在的需求是,查詢2006年7月1日到2007年7月31日的所有訂單,並按requireddate字段排序,查詢sql代碼如下:
USE TSQLFundamentals2008; GO -- 查詢2006年7月1日到2007年7月31日的所有訂單,並按requireddate字段排序 SELECT orderid,orderdate,requireddate,shippeddate,shipname,shipaddress FROM Sales.Orders WHERE orderdate>='20060701' AND orderdate<'20070801' ORDER BY requireddate;
注意,這個表只有主鍵orderid的聚集索引外,沒有建立任何索引。執行查詢查看執行計划,如下圖。
從上面的執行計划可以看出,在排序和聚集索引查找方面比較耗時。首先看排序,因為是by requireddate排序的,所以對requireddate字段要建立單個字段索引,代碼如下。
IF NOT EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('Sales.Orders') AND name='idx_nc_requireddate') CREATE NONCLUSTERED INDEX idx_nc_requireddate ON Sales.Orders(requireddate); GO
然后因為where條件中是按orderdate字段來限定范圍的,所以對orderdate字段要建立單個字段索引,代碼如下。
IF NOT EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('Sales.Orders') AND name='idx_nc_orderdate') CREATE NONCLUSTERED INDEX idx_nc_orderdate ON Sales.Orders(orderdate); GO
因為要查詢的字段為orderid,orderdate,requireddate,shippeddate,shipname,shipaddress,所以我們可以針對這幾個字段建立一個組合字段索引,代碼如下。
IF NOT EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('Sales.Orders') AND name='idx_orders_orderid_orderdate_shipaddress') CREATE NONCLUSTERED INDEX idx_orders_orderid_orderdate_shipaddress ON Sales.Orders(orderid,orderdate,requireddate,shippeddate,shipname,shipaddress); GO
最后,我們再重新運行一次查詢,查看執行計划,如下圖。
從執行計划中可以看到,后面那個已經變成了非聚集索引查詢了,說明我們創建的索引起作用了。具體是創建單個字段索引,組合字段索引還是兩個都要創建,這個要在實際的項目中反復試驗。