sql server 2008学习4 设计索引的建议
索引設(shè)計(jì)的建議:
一.檢查where子句和連接條件列
當(dāng)一個(gè)查詢提交到sql server時(shí),查詢優(yōu)化器嘗試為查詢中引用的所有表查找最佳的數(shù)據(jù)訪問(wèn)機(jī)制,
一下是它所進(jìn)行的方式。
1.優(yōu)化器識(shí)別Where子句和連接條件中包含的列、
2.接著優(yōu)化器檢查這些列的索引.
3.優(yōu)化器通過(guò)從索引上維護(hù)的統(tǒng)計(jì)確定子句的選擇性(也就是返回多少行),評(píng)估每個(gè)索引的有效性
4.最終,優(yōu)化器根據(jù)前面幾個(gè)步驟中收集的信息,評(píng)估讀取所限定的行開(kāi)銷(xiāo)最低的方法.
下面看個(gè)例子:? Table_1表內(nèi) 又 30000條數(shù)據(jù)
執(zhí)行查詢:
查看結(jié)果:
邏輯讀取的次數(shù)為 95次.
下面加上where? 條件句, where 的列 是 含有聚集索引的.
結(jié)果:
很明顯, 邏輯讀 次數(shù)減少了兩次.
下面看 where 條件句,where 的列 不含有索引的:
查詢的結(jié)果:
總結(jié):
where 子句列 幫助 優(yōu)化器選擇 一個(gè)對(duì) 查詢最優(yōu)的索引操作. 這也使用于 兩個(gè)表之間的連接條件中使用的列.
優(yōu)化器 查找在 where子句 或連接條件列上的索引,如果可用,考慮使用該索引 來(lái)從表中檢索行,查詢優(yōu)化器在執(zhí)行一個(gè)查詢時(shí),
考慮where子句或連接條件列上的索引. 因此,在where子句或連接條件中 頻繁使用的列上有 索引將 幫助查詢優(yōu)化器避免基本表的掃描.
注意:? 當(dāng)一個(gè)表中的數(shù)據(jù)總量非常小以至于可以 放入一個(gè)單獨(dú)的頁(yè)面(8kb)時(shí),表掃描可能比索引查找工作 得更好,
二: 使用 窄索引
應(yīng)該避免在索引中使用 寬數(shù)據(jù)類(lèi)型 的列. 比如 字符串類(lèi)型(char,varchar,nchar ,nvarchar)的列有時(shí)候可能和二進(jìn)制類(lèi)型一樣大.
窄索引可以再8kb的索引頁(yè)面中 容納比 寬索引 更多的行,這將有一下效果:
1.減少 i/o數(shù)量 (讀取更少的8kb頁(yè)面)
2.使數(shù)據(jù)庫(kù)緩存更有效,因?yàn)?sql server 可以緩存更少的索引頁(yè)面,從而減少內(nèi)存中的索引頁(yè)面所需的邏輯讀操作.
3.減少數(shù)據(jù)庫(kù)的存儲(chǔ)空間.
下面看個(gè)例子:
表a
id為主鍵, 所以 a有個(gè)聚集索引, 那么id列的數(shù)據(jù)類(lèi)型是 int,a表有數(shù)據(jù)27行數(shù)據(jù),說(shuō)明所有的 索引 總大小為 4*27 byte, 一個(gè)索引頁(yè)面(8kb)完全可以容得下.
sys.indexes系統(tǒng)表 在每個(gè)數(shù)據(jù)庫(kù)中保存,包含了數(shù)據(jù)庫(kù)中所有索引的基本信息.
DMF? sys.dm_db_index_physical_stats 包含了關(guān)于索引上統(tǒng)計(jì)的更詳細(xì)信息.
下面看sql語(yǔ)句:?
select i.name,i.type_desc,s.page_count,s.record_count,s.index_level from sys.indexes ijoin sys.dm_db_index_physical_stats(DB_ID(N'test'),OBJECT_ID(N'dbo.a'),null,null,'DETAILED') as son i.index_id=s.index_id where i.OBJECT_ID=OBJECT_ID(N'dbo.a') 獲取如下 結(jié)果: .csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) } .csharpcode pre { margin: 0 } .csharpcode .rem { color: rgba(0, 128, 0, 1) } .csharpcode .kwrd { color: rgba(0, 0, 255, 1) } .csharpcode .str { color: rgba(0, 96, 128, 1) } .csharpcode .op { color: rgba(0, 0, 192, 1) } .csharpcode .preproc { color: rgba(204, 102, 51, 1) } .csharpcode .asp { background-color: rgba(255, 255, 0, 1) } .csharpcode .html { color: rgba(128, 0, 0, 1) } .csharpcode .attr { color: rgba(255, 0, 0, 1) } .csharpcode .alt { background-color: rgba(244, 244, 244, 1); width: 100%; margin: 0 } .csharpcode .lnum { color: rgba(96, 96, 96, 1) }說(shuō)明 索引頁(yè)數(shù) 是1頁(yè), index_leval =0說(shuō)明是 聚集索引.
下面使用寬索引 的一個(gè)例子:
b表結(jié)果如下:? name列有一個(gè)? 非聚集索引,索引名字為: IX_b? 由于name 的數(shù)據(jù)類(lèi)型為 char(500),b內(nèi)數(shù)據(jù)有23行, 說(shuō)明非聚集索引占用的大小事 23*500byte,那么超出了一個(gè)頁(yè)面的大小,
按照預(yù)測(cè),name的索引將存在兩個(gè)索引頁(yè)面, 下面用sql語(yǔ)句來(lái)證實(shí)這個(gè)結(jié)論.
sql語(yǔ)句:
select i.name,i.type_desc,s.page_count,s.record_count,s.index_level from sys.indexes ijoin sys.dm_db_index_physical_stats(DB_ID(N'test'),OBJECT_ID(N'dbo.b'),null,null,'DETAILED') as son i.index_id=s.index_id where i.OBJECT_ID=OBJECT_ID(N'dbo.b') .csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) } .csharpcode pre { margin: 0 } .csharpcode .rem { color: rgba(0, 128, 0, 1) } .csharpcode .kwrd { color: rgba(0, 0, 255, 1) } .csharpcode .str { color: rgba(0, 96, 128, 1) } .csharpcode .op { color: rgba(0, 0, 192, 1) } .csharpcode .preproc { color: rgba(204, 102, 51, 1) } .csharpcode .asp { background-color: rgba(255, 255, 0, 1) } .csharpcode .html { color: rgba(128, 0, 0, 1) } .csharpcode .attr { color: rgba(255, 0, 0, 1) } .csharpcode .alt { background-color: rgba(244, 244, 244, 1); width: 100%; margin: 0 } .csharpcode .lnum { color: rgba(96, 96, 96, 1) }查詢結(jié)果如下:
果然,看到 IX_b record_count =23的 行, 它的 page_count是2 ,說(shuō)明我們之前的猜想是正確的.
這就是寬索引的劣勢(shì).
三:檢查列的唯一性.
在一個(gè)具有很小范圍的可能值的列(如性別,只有,f和m)上創(chuàng)建索引,對(duì)性能是沒(méi)有很大幫助的.
因?yàn)椴樵儍?yōu)化器不能使用索引有效的減少返回的行.?
考慮只有兩個(gè)唯一值 的 性別列(F和M).當(dāng)執(zhí)行一個(gè) 具有使用 性別列的where子句查詢時(shí),最終從表中得打很大數(shù)量的行,導(dǎo)致開(kāi)銷(xiāo)很大的表,或聚集索引掃描.
結(jié)論:
所以 使用where子句中的列 具有 大量的唯一行,一限制訪問(wèn)的行數(shù),是個(gè)首選的方案. 應(yīng)該在 這些列上 創(chuàng)建索引,來(lái)幫助 查詢優(yōu)化器
訪問(wèn)小的結(jié)果集.
而且,在創(chuàng)建多個(gè)列上的索引時(shí)(符合索引),列的順序是有關(guān)系的.在某些情況下,先使用最有選擇性的列將使索引行的列更有效率.
可以使用下面的語(yǔ)句 來(lái)判斷 列的選擇性.
test1 自己隨意定義的表select count(distinct EventClass) as 不同的值,count(EventClass) as 多少行,cast(count(distinct EventClass) as decimal) as 選擇性 from test1結(jié)果如下:
具有最高的唯一值數(shù)量(或選擇性)的列 是 where子句 或連接條件 中引用的索引的 最佳候選.
四:考慮索引類(lèi)型
`sql server主要有兩種索引,聚集索引和非聚集索引,這兩種類(lèi)型的索引 都為 B-樹(shù) 結(jié)構(gòu)。兩者之間的主要區(qū)別 是
聚集索引的葉子頁(yè)面 是表的數(shù)據(jù)頁(yè)面,因此數(shù)據(jù)和其指針的順序相同,這意味著 聚集索引就是該表。
下一篇 ,主要講述這兩種索引。
總結(jié)
以上是生活随笔為你收集整理的sql server 2008学习4 设计索引的建议的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 深圳学区房和学位房的区别?
- 下一篇: 如何正确处理废旧家居陈设?