(四)其他書上沒有的索引使用經驗總結 1
、用聚合索引比用不是聚合索引的主鍵速度快
下面是例項語句:(都是提取
25萬條資料)
select gid,fariqi,neibuyonghu,reader,title from tgongwen where fariqi='2004-9-16'
3326毫秒
select gid,fariqi,neibuyonghu,reader,title from tgongwen where gid<=250000
4470毫秒
這裡,用聚合索引比用不是聚合索引的主鍵速度快了近
1/4。 2
、用聚合索引比用一般的主鍵作
order by
時速度快,特別是在小資料量情況下
select gid,fariqi,neibuyonghu,reader,title from tgongwen order by fariqi
用時:12936
select gid,fariqi,neibuyonghu,reader,title from tgongwen order by gid
用時:18843
這裡,用聚合索引比用一般的主鍵作
order by
時,速度快了
3/10
。事實上,如果資料量很小的話,用聚集索引作為排序列要比使用非聚集索引速度快得明顯的多;而資料量如果很大的話,如
10萬以上,則二者的速度差別不明顯。 3
、使用聚合索引內的時間段,搜尋時間會按資料佔整個資料表的百分比成比例減少,而無論聚合索引使用了多少個
select gid,fariqi,neibuyonghu,reader,title from tgongwen where fariqi>'2004-1-1'
用時:6343
毫秒(提取
100萬條)
select gid,fariqi,neibuyonghu,reader,title from tgongwen where fariqi>'2004-6-6'
用時:3170
毫秒(提取
50萬條)
select gid,fariqi,neibuyonghu,reader,title from tgongwen where fariqi='2004-9-16'
用時:3326
毫秒(和上句的結果一模一樣。如果採集的數量一樣,那麼用大於號和等於號是一樣的)
select gid,fariqi,neibuyonghu,reader,title from tgongwen where fariqi>'2004-1-1' and fariqi<'2004-6-6'
用時:3280毫秒
4 、日期列不會因為有分秒的輸入而減慢查詢速度
下面的例子中,共有
100萬條資料,
2023年1
月1日以後的資料有
50萬條,但只有兩個不同的日期,日期精確到日;之前有資料
50萬條,有
5000
個不同的日期,日期精確到秒。
select gid,fariqi,neibuyonghu,reader,title from tgongwen where fariqi>'2004-1-1' order by fariqi
用時:6390毫秒
select gid,fariqi,neibuyonghu,reader,title from tgongwen where fariqi<'2004-1-1' order by fariqi
用時:6453毫秒
(五)其他注意事項
「水可載舟,亦可覆舟」,索引也一樣。索引有助於提高檢索效能,但過多或不當的索引也會導致系統低效。因為使用者在表中每加進乙個索引,資料庫就要做更多的工作。過多的索引甚至會導致索引碎片。
所以說,我們要建立乙個「適當」的索引體系,特別是對聚合索引的建立,更應精益求精,以使您的資料庫能得到高效能的發揮。
當然,在實踐中,作為乙個盡職的資料庫管理員,您還要多測試一些方案,找出哪種方案效率最高、最為有效。
二、改善
sql語句
很多人不知道
sql語句在
sql server
中是如何執行的,他們擔心自己所寫的
sql語句會被
sql server
誤解。比如:
select * from table1 where name='zhangsan' and tid > 10000
和執行: select * from table1 where tid > 10000 and name='zhangsan'
一些人不知道以上兩條語句的執行效率是否一樣,因為如果簡單的從語句先後上看,這兩個語句的確是不一樣,如果
tid是乙個聚合索引,那麼後一句僅僅從表的
10000
條以後的記錄中查詢就行了;而前一句則要先從全表中查詢看有幾個
name='zhangsan'
的,而後再根據限制條件條件
tid>10000
來提出查詢結果。
事實上,這樣的擔心是不必要的。
sql server
中有乙個「查詢分析優化器」,它可以計算出
where
子句中的搜尋條件並確定哪個索引能縮小表掃瞄的搜尋空間,也就是說,它能實現自動優化。
雖然查詢優化器可以根據
where
子句自動的進行查詢優化,但大家仍然有必要了解一下「查詢優化器」的工作原理,如非這樣,有時查詢優化器就會不按照您的本意進行快速查詢。
在查詢分析階段,查詢優化器檢視查詢的每個階段並決定限制需要掃瞄的資料量是否有用。如果乙個階段可以被用作乙個掃瞄引數(
sarg
),那麼就稱之為可優化的,並且可以利用索引快速獲得所需資料。
sarg
的定義:用於限制搜尋的乙個操作,因為它通常是指乙個特定的匹配,乙個值得範圍內的匹配或者兩個以上條件的
and連線。形式如下: 列名
操作符《常數或
變數》或《常數或
變數》
操作符列名
列名可以出現在操作符的一邊,而常數或變數出現在操作符的另一邊。如:
name=』
張三』
**>5000
5000<**
name=』
張三』and
**>5000
如果乙個表示式不能滿足
sarg
的形式,那它就無法限制搜尋的範圍了,也就是
sql server
必須對每一行都判斷它是否滿足
where
子句中的所有條件。所以乙個索引對於不滿足
sarg
形式的表示式來說是無用的。
介紹完sarg
後,我們來總結一下使用
sarg
以及在實踐中遇到的和某些資料上結論不同的經驗: 1
、like
語句是否屬於
sarg
取決於所使用的萬用字元的型別 如:
name like 『
張%』
,這就屬於
sarg
而:name like 『%張』,
就不屬於
sarg。
原因是萬用字元
%在字串的開通使得索引無法使用。 2
、or
會引起全表掃瞄
name=』
張三』and
**>5000
符號sarg
,而:name=』
張三』or
**>5000
則不符合
sarg
。使用or
會引起全表掃瞄。 3
、非操作符、函式引起的不滿足
sarg
形式的語句
不滿足sarg
形式的語句最典型的情況就是包括非操作符的語句,如:
not、!=、
<>
、!<
、!>
、not exists
、not in
、not like
等,另外還有函式。
下面就是幾個不滿足
sarg
形式的例子:
abs(
**)<5000
name like 『%
三』 有些表示式,如:
where
***2>5000
sql server
也會認為是
sarg
,sql server
會將此式轉化為:
where
**>2500/2
但我們不推薦這樣使用,因為有時
sql server
不能保證這種轉化與原始表示式是完全等價的。 4
、in
的作用相當與
or
語句:
select * from table1 where tid in (2,3)
和select * from table1 where tid=2 or tid=3
是一樣的,都會引起全表掃瞄,如果
tid上有索引,其索引也會失效。 5
、盡量少用
not
深入淺出理解索引
一 深入淺出理解索引結構 實際上,您可以把索引理解為一種特殊的目錄。sql server提供了兩種索引 聚集索引 clustered index,也稱聚類索引 簇集索引 和非聚集索引 nonclustered index,也稱非聚類索引 非簇集索引 下面,我們舉例來說明一下聚集索引和非聚集索引的區別...
深入淺出理解索引
一 深入淺出理解索引結構 實際上,您可以把索引理解為一種特殊的目錄。sql server提供了兩種索引 聚集索引 clustered index,也稱聚類索引 簇集索引 和非聚集索引 nonclustered index,也稱非聚類索引 非簇集索引 下面,我們舉例來說明一下聚集索引和非聚集索引的區別...
深入淺出空間索引 2
第一篇講到了傳統的索引如b樹不能很好的支援空間資料,比如點 poi等 線 道路 河流等 面 行政邊界 住宅區等 本篇將對空間索引進行簡單分類,然後介紹網格索引。深入淺出空間索引1 一 空間索引有哪幾種?傳統索引使用雜湊和樹這兩類最基本的資料結構。空間索引雖然更為複雜,但仍然發展於這兩種資料結構。因此...