要了解索引訪問方法,首先要知道索引的結構。
1.表和索引的結構
頁頁是sql server儲存資料的基本單位,大小為8kb,可以儲存表資料、索引資料、執行計畫資料、分配位圖、可用空間資訊。頁是sql server可以讀寫的最小i/o單位。即便是讀取一行資料,它也要把整個頁載入到快取並從快取中讀取資料。
區區是由8個連續頁組成的分配單元。
堆堆是指不含聚集索引的表,它的資料不按任何順序進行儲存。
聯絡乙個堆中的資料的唯一結構是被稱為索引分配對映(iam)的乙個點陣圖頁,當掃瞄物件時,sql server使用iam頁來遍歷該物件的資料。
聚集索引:
它的葉級表中維護所有資料,按照索引鍵列的順序儲存在索引的葉級。在索引頁級別的上層,索引還維護著其他級別,每個級別都概況了它下面的級別,非葉級索引上的每一行指向它下一級別的整個頁。
堆上的非聚集索引:
與聚集索引的唯一區別是非聚集索引的葉級頁只包含索引鍵列和指向特定資料行的行定位符,稱為rid。當通過索引查詢到特定的資料行後,sqlserver必須在seek操作之後執行rid lookup操作,該操作用於讀取包含資料行的頁。
聚集表上的非聚集索引:
指向特定資料行的行定位符是聚集鍵的值,不是rid。
2.索引訪問方法
表掃瞄/無序聚集索引掃瞄
當表中沒有索引時,連續的掃瞄表中的所有資料頁。sql server將根據該錶的iam頁指示磁碟取數臂按物理順序掃瞄屬於該錶的區。
當表包含聚集索引時,所採取的方法將是無序聚集索引掃瞄。
示例sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.orders
索引:create clustered index idx_cl_od on dbo.orders(orderdate);
表orders結構: orderid,custid,empid,shipperid,orderdate,filler
覆蓋非聚集索引掃瞄
sql server 只訪問索引資料就可以找到滿足查詢所需的全部資料,不需要訪問完整的資料行。
示例sql:select orderid from dbo.orders
索引:alter table [dbo].[orders] add constraint [pk_orders] primary key nonclustered
([orderid] asc
)有序聚集索引掃瞄
按照鏈結列表對聚集索引葉級執行的完整掃瞄 操作。
示例sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.orders order by orderdate
索引:create clustered index idx_cl_od on dbo.orders(orderdate);
不同於無序索引掃瞄,有序掃瞄的效能取決於索引的碎片級別。
有序覆蓋非聚集索引掃瞄
與有序聚集索引掃瞄類似,但是覆蓋非聚集索引掃瞄時,因為它涉及更少的頁,它的成本肯定比聚集索引索引掃瞄要低。
示例sql:select orderid, orderdate from dbo.orders order by orderid
非聚集索引索引查詢+有序區域性掃瞄+lookups
通常用於小範圍查詢,且用到的非聚集索引沒有覆蓋該查詢。
示例sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.orders where orderid between 101 and 200
無序非聚集索引掃瞄 + lookups
通常符合以下情況時,優化器會選擇此種訪問方法:
該查詢的選擇性足夠高
最適合某查詢的索引並不覆蓋該查詢
索引沒有按順序維護被查詢鍵
示例sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.orders where custid = 『』
聚集索引查詢+有序區域性掃瞄
對於按聚集索引的第乙個鍵列進行篩選的範圍查詢,優化器通常使用這種方法。
示例sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.orders where orderdate = 『20060212』
這種方法的好處是不涉及lookups.
覆蓋非聚集索引查詢+有序區域性掃瞄
訪問方法與上乙個類似,唯一的區別是非聚集索引。相對於上乙個訪問方法,這個方法的好處在於非聚集索引的的葉級頁比聚集索引的葉級頁能夠容納更多的行。
示例sql: select shipperid,orderdate, custid from dbo.orders
where shipperid='c' and orderdate >='20060101' and orderdate
create nonclustered index idx_nc_sid_od_cid
on dbo.orders(shipperid, orderdate, custid);
3.索引優化等級
需要優化的sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.orders where orderid > 999001
1.這個表沒有任何索引:該計畫將使用表掃瞄
2.接下來優化,建立乙個非聚集覆蓋索引,且不把篩選列(orderid)作為第乙個篩選列:
create index idx_nc_od_i_oid_cid_eid_sid
on performance.dbo.orders(orderdate)
include(orderid,custid,empid,shipperid);
優化器將採用覆蓋非聚集索引掃瞄
create nonclustered index idx_nc_od_i_oid
on dbo.orders(orderdate)
include(orderid);
優化器將採用非聚集索引掃瞄+lookup,這個查詢依賴於選擇性。選擇性越高,效能越高。
4.繼續優化:在orderid上建立非聚集非覆蓋索引,
create unique nonclustered index idx_unc_oid
on dbo.orders(orderid);
優化器將採用非聚集索引查詢+lookup
5.繼續優化:在orderid上建立聚集索引
create unique clustered index idx_cl_oid on dbo.orders(orderid);
這個計畫主要不涉及lookup,
6.繼續優化:
最佳優化應該是把orderid作為鍵列,並把其他列定義為包含性非鍵列的非聚集覆蓋索引。
create unique nonclustered index idx_unc_oid_i_od_cid_eid_sid
on dbo.orders(orderid)
include(orderdate, custid, empid, shipperid);
這個計畫的邏輯與上乙個類似,只是非聚集覆蓋索引有序區域性掃瞄讀取的頁更少。
MySQL優化(三) 索引原理及索引優化
b tree索引,它是目前關係型資料庫中查詢資料最為常用和有效的索引,大多數儲存引擎都支援這種索引。使用b tree這個術語,是因為mysql在create table或其它語句中使用了這個關鍵字,但實際上不同的儲存引擎可能使用不同的資料結構,比如innodb就是使用的b tree。中的b是指bal...
索引優化及原理
oracle 之sql優化 索引的基本原理 一 1 索引的基本概念 1 建立索引的目的 以索引小的io換取表的大io。何時建立索引 當訪問的資料塊少於表中20 的資料時,建議使用索引。2 索引的 會使insert delete速度變慢 索引個數多的話速度就會慢 對於update語句,需要先判斷是否要...
Mysql 索引及優化
索引是什麼?相信大家都用過字典。你是怎麼從厚厚的新華字典中找到你需要找到的那個字的呢?又是怎麼從一本書中快速定位到你需要的章節?我們都是通過書中的目錄,然後根據目錄中的頁碼定位到我們要的資訊。同樣在mysql中也是這樣為我們準備了乙份目錄。當你去通過sql語句查詢的時候用不用索引,以及怎麼用索引。決...