如何创建索引
通過前面二篇文章我們基本學(xué)會(huì)了如何結(jié)合執(zhí)行計(jì)劃分析出某Sql語句的性能問題,既然有性能問題的地方已經(jīng)找到了,接下來就是如何優(yōu)化查詢來提高查詢性能,而優(yōu)化查詢最重要的武器就是創(chuàng)建索引,這篇文章就來總結(jié)如何創(chuàng)建索引來提高查詢速度,主要從以下幾個(gè)方面來總結(jié)。
了解索引
? 1,索引是什么?
在Sql Server中,索引是一種增強(qiáng)式的存在,這表示即使沒有索引,Sql Server的功能并不會(huì)受到影響。索引是對(duì)數(shù)據(jù)庫表中一列或多列的值進(jìn)行排序的一種結(jié)構(gòu)(B樹),使用索引可快速訪問數(shù)據(jù)庫表中的特定信息。
2,為什么要使用索引?
就是提高查詢性能。
3,有哪些索引?
主要分為聚集索引(CLUSTERED INDEX)和非聚集索引(NONCLUSTERED INDEX)兩種,聚集索引指的是一列或多列的物理順序和邏輯順序是一致的,一個(gè)數(shù)據(jù)庫表只能有一個(gè)聚集索引,我們通常將主鍵(一般為自增int型)設(shè)為聚集索引。而非聚集索引則可以有多個(gè),而且非聚集索引并不會(huì)改變數(shù)據(jù)庫表的物理結(jié)構(gòu)。
創(chuàng)建索引的語法
1,創(chuàng)建索引,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); GO2,刪除索引,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結(jié)合實(shí)例演示如何創(chuàng)建索引
表結(jié)構(gòu)如下:
現(xiàn)在的需求是,查詢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;注意,這個(gè)表只有主鍵orderid的聚集索引外,沒有建立任何索引。執(zhí)行查詢查看執(zhí)行計(jì)劃,如下圖。
從上面的執(zhí)行計(jì)劃可以看出,在排序和聚集索引查找方面比較耗時(shí)。首先看排序,因?yàn)槭莃y?requireddate排序的,所以對(duì)requireddate字段要建立單個(gè)字段索引,代碼如下。
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然后因?yàn)閣here條件中是按orderdate字段來限定范圍的,所以對(duì)orderdate字段要建立單個(gè)字段索引,代碼如下。
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因?yàn)橐樵兊淖侄螢閛rderid,orderdate,requireddate,shippeddate,shipname,shipaddress,所以我們可以針對(duì)這幾個(gè)字段建立一個(gè)組合字段索引,代碼如下。
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最后,我們?cè)僦匦逻\(yùn)行一次查詢,查看執(zhí)行計(jì)劃,如下圖。
從執(zhí)行計(jì)劃中可以看到,后面那個(gè)已經(jīng)變成了非聚集索引查詢了,說明我們創(chuàng)建的索引起作用了。具體是創(chuàng)建單個(gè)字段索引,組合字段索引還是兩個(gè)都要?jiǎng)?chuàng)建,這個(gè)要在實(shí)際的項(xiàng)目中反復(fù)試驗(yàn)。
參考資料
1,CareySon的?T-SQL查詢進(jìn)階--理解SQL Server中索引的概念,原理以及其他
2,田園里的蟋蟀的?程序員眼中的 SQL Server-執(zhí)行計(jì)劃教會(huì)我如何創(chuàng)建索引?
總結(jié)
- 上一篇: 运维-系统架构师经验总结:
- 下一篇: 漫谈中国自主杀毒引擎