原文:
sql開發中容易忽視的一些小地方(六)
事由:今天在北京俱樂部msn群中和網友討論了關於索引對delete的影響問題,事後感覺非常汗顏,因為我的隨口導致錯誤連篇。大致話題是這樣的,並非原話:
[討論:]delete course where classid=500001 classid上沒有建立任何索引,為了提高刪除效率,如果在classid上建立乙個非聚集索引會不會提高刪除的效率呢?
我當時的觀點:不能。
我當時的理由:資料庫在執行刪除時,如果在classid上建立了非聚集索引,首先按這個非聚集索引查詢資料,找到索引行後,根據索引行後面帶的聚集索引位址最後找到真正的物理資料行,並且執行刪除,這個過程看起來沒有作用,只能建立聚集索引來提高刪除效率,因為如果classid是聚集索引,那麼直接聚集索引刪除,此時的效率最高。
下班後對這個話題再次想了下,覺的自己的觀點都自相矛盾,既然知道刪除時,會在條件列上試圖應用已經存在的索引,那麼為什麼建立非聚集索引會無效呢?如果表的資料相當大,classid上如果沒有任何索引,查詢資料時就要執行表掃瞄,而表掃瞄的速度是相當慢的,為此為了證明下這個問題,我特意做了乙個示意性的實驗。
建立兩個表course 和course2,建立語句如下,它們唯一的區別就在於索引,course表中classid上建立了非聚集索引,而course2上沒有建立任何索引。
create table [dbo].[course](
[id] [
int] identity(1,
1) not null,
[scoursename] [nchar](
10) collate chinese_prc_ci_as null,
[classid] [
int] null,
constraint [pk_ckh] primary key clustered
([id] asc
)with (ignore_dup_key
=off) on [primary]
) on [primary]
--建立索引
create index ix_classid
on course(classid)
create table [dbo].[course2](
[id] [
int] identity(1,
1) not null,
[scoursename] [nchar](
10) collate chinese_prc_ci_as null,
[classid] [
int] null,
constraint [pk_ckh2] primary key clustered
([id] asc
)with (ignore_dup_key
=off) on [primary]
) on [primary]
實驗過程:
第一步:分別給兩個表插入相當的資料1000行,然後刪除第500條記錄。
delete course
where
classid
=500
delete course2
where
classid
=500
執行計畫圖如下:我們可以看到在執行刪除時,資料庫分為三部分:
1:查詢到要刪除的資料行;
2:包含乙個top操作。
3:執行聚集索引刪除。
區別一:由於course表的classid上建立了索引,所以查詢時按pk_classid來查詢,course2表的classid由於沒有任何的索引,為了查詢到要刪除的資料行,就只能按聚集索引查詢,此時實際上是全表掃瞄。
區別二:系統開銷不同,讓人意外的是,結果表明好像白天的觀點是正確的,建立了索引的coure表在開銷上比沒有建立索引的course2還大一點。
分析區別二的原因:我們來看下聚集索引刪除的具體內容,下面是在條件列classid上建立了非聚集索引的表course表在發生刪除時的執行計畫圖,它在刪除後需要維護索引pk_classid,占用部分的系統開銷。而沒有建立索引的表course2由於沒有索引維護的額外開銷,所以反而佔優勢。
第二步:分別給兩個表插入相當的資料10000行,然後刪除第5000條記錄。
區別同第一步。難道我的觀點真的正確?
第三步:分別給兩個表插入相當的資料100000行,然後刪除第50000條記錄。執行計畫圖如下:
區別一:同前兩步的區別一。
區別二:系統開銷不同,此時會發現建立了索引的course表在開銷上佔5%,而沒有建立索引的course2表佔了95%,這可是10倍的區別啊。
第四步:分別給兩個表插入相當的資料1000000行,然後刪除第500000條記錄。
區別同第三步。
總結:當刪除語句的條件列沒有建立索引時分兩種情況:
第一:資料量較小,我測試時在10000以下,此時兩者的差別不大,反而會因為建立了索引而引起磁碟開銷。開銷差距不大是因為資料量小時,即使全表掃瞄速度也不慢,此時索引的優勢並不明顯。
第二:資料量較大,我測試時在100000以上,此時兩者的差別較大。條件列建立了索引的表明顯效率高。
第三:歸根結底,系統的主要開銷還是在刪除的第一步,查詢資料行上。能更快查詢到刪除行的方案效率最高。
SQL開發中容易忽視的一些小地方 一
sql開發中容易忽視的一些小地方 一 寫此系列文章緣由 做開發三年來 b s 發現基於web 架構的專案技術主要分兩大方面 第一 c 它是程式的基礎,也可是其它開發語言,沒有開發語言也就不存在應用程式.第二 資料庫,現在是資訊化世界,大多數資訊都可以通過資料庫儲存來交換資訊.常與應用程式互相交流資訊...
SQL開發中容易忽視的一些小地方 一
原文 sql開發中容易忽視的一些小地方 一 寫此系列文章緣由 做開發三年來 b s 發現基於web 架構的專案技術主要分兩大方面 第一 c 它是程式的基礎,也可是其它開發語言,沒有開發語言也就不存在應用程式.第二 資料庫,現在是資訊化世界,大多數資訊都可以通過資料庫儲存來交換資訊.常與應用程式互相交...
SQL開發中容易忽視的一些小地方 一
原文 sql開發中容易忽視的一些小地方 一 寫此系列文章緣由 做開發三年來 b s 發現基於web 架構的專案技術主要分兩大方面 第一 c 它是程式的基礎,也可是其它開發語言,沒有開發語言也就不存在應用程式.第二 資料庫,現在是資訊化世界,大多數資訊都可以通過資料庫儲存來交換資訊.常與應用程式互相交...