人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)

海量數(shù)據(jù)庫查詢語句

發(fā)布日期:2022-01-30 19:28 | 文章來源:CSDN
以下代碼說明了我們實例中數(shù)據(jù)庫的“紅頭文件”一表的部分數(shù)據(jù)結(jié)構(gòu):
CREATETABLE[dbo].[TGongwen](--TGongwen是紅頭文件表名
[Gid][int]IDENTITY(1,1)NOTNULL,
--本表的id號,也是主鍵
[title][varchar](80)COLLATEChinese_PRC_CI_ASNULL,
--紅頭文件的標(biāo)題
[fariqi][datetime]NULL,
--發(fā)布日期
[neibuYonghu][varchar](70)COLLATEChinese_PRC_CI_ASNULL,
--發(fā)布用戶
[reader][varchar](900)COLLATEChinese_PRC_CI_ASNULL,
--需要瀏覽的用戶。每個用戶中間用分隔符“,”分開
)ON[PRIMARY]TEXTIMAGE_ON[PRIMARY]
GO

下面,我們來往數(shù)據(jù)庫中添加1000萬條數(shù)據(jù):

declare@iint
set@i=1
while@i<=250000
begin
insertintoTgongwen(fariqi,neibuyonghu,reader,title)values('2004-2-5','通信科','通信科,辦公室,王局長,劉局長,張局長,admin,刑偵支隊,特勤支隊,交巡警支隊,經(jīng)偵支隊,戶政科,治安支隊,外事科','這是最先的25萬條記錄')
set@i=@i+1
end
GO

declare @i int

set @i=1

while @i<=250000

begin

insert into Tgongwen(fariqi,neibuyonghu,reader,title) values('2004-9-16','辦公室','辦公室,通信科,王局長,劉局長,張局長,admin,刑偵支隊,特勤支隊,交巡警支隊,經(jīng)偵支隊,戶政科,外事科','這是中間的25萬條記錄')

set @i=@i+1

end

GO

declare@hint
set@h=1
while@h<=100
begin
declare@iint
set@i=2002
while@i<=2003
begin
declare@jint
set@j=0
while@j<50
begin
declare@kint
set@k=0
while@k<50
begin
insertintoTgongwen(fariqi,neibuyonghu,reader,title)values(cast(@iasvarchar(4))+'-8-153:'+cast(@jasvarchar(2))+':'+cast(@jasvarchar(2)),'通信科','辦公室,通信科,王局長,劉局長,張局長,admin,刑偵支隊,特勤支隊,交巡警支隊,經(jīng)偵支隊,戶政科,外事科','這是最后的50萬條記錄')
set@k=@k+1
end
set@j=@j+1
end
set@i=@i+1
end
set@h=@h+1
end
GO
declare@iint
set@i=1
while@i<=9000000
begin
insertintoTgongwen(fariqi,neibuyonghu,reader,title)values('2004-5-5','通信科','通信科,辦公室,王局長,劉局長,張局長,admin,刑偵支隊,特勤支隊,交巡警支隊,經(jīng)偵支隊,戶政科,治安支隊,外事科','這是最后添加的900萬條記錄')
set@i=@i+1000000
end
GO

通過以上語句,我們創(chuàng)建了25萬條由通信科于200425發(fā)布的記錄,25萬條由辦公室于200496發(fā)布的記錄,2002年和2003年各1002500條相同日期、不同分秒的由通信科發(fā)布的記錄(共50萬條),還有由通信科于200455發(fā)布的900萬條記錄,合計1000萬條。

一、因情制宜,建立“適當(dāng)”的索引

建立“適當(dāng)”的索引是實現(xiàn)查詢優(yōu)化的首要前提。

索引(index)是除表之外另一重要的、用戶定義的存儲在物理介質(zhì)上的數(shù)據(jù)結(jié)構(gòu)。當(dāng)根據(jù)索引碼的值搜索數(shù)據(jù)時,索引提供了對數(shù)據(jù)的快速訪問。事實上,沒有索引,數(shù)據(jù)庫也能根據(jù)SELECT語句成功地檢索到結(jié)果,但隨著表變得越來越大,使用“適當(dāng)”的索引的效果就越來越明顯。注意,在這句話中,我們用了“適當(dāng)”這個詞,這是因為,如果使用索引時不認真考慮其實現(xiàn)過程,索引既可以提高也會破壞數(shù)據(jù)庫的工作性能。

(一)深入淺出理解索引結(jié)構(gòu)

實際上,您可以把索引理解為一種特殊的目錄。微軟的SQL SERVER提供了兩種索引:聚集索引(clustered index,也稱聚類索引、簇集索引)和非聚集索引(nonclustered index,也稱非聚類索引、非簇集索引)。下面,我們舉例來說明一下聚集索引和非聚集索引的區(qū)別:

其實,我們的漢語字典的正文本身就是一個聚集索引。比如,我們要查“安”字,就會很自然地翻開字典的前幾頁,因為“安”的拼音是“an”,而按照拼音排序漢字的字典是以英文字母“a”開頭并以“z”結(jié)尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”開頭的部分仍然找不到這個字,那么就說明您的字典中沒有這個字;同樣的,如果查“張”字,那您也會將您的字典翻到最后部分,因為“張”的拼音是“zhang”。也就是說,字典的正文部分本身就是一個目錄,您不需要再去查其他目錄來找到您需要找的內(nèi)容。

我們把這種正文內(nèi)容本身就是一種按照一定規(guī)則排列的目錄稱為“聚集索引”。

如果您認識某個字,您可以快速地從自動中查到這個字。但您也可能會遇到您不認識的字,不知道它的發(fā)音,這時候,您就不能按照剛才的方法找到您要查的字,而需要去根據(jù)“偏旁部首”查到您要找的字,然后根據(jù)這個字后的頁碼直接翻到某頁來找到您要找的字。但您結(jié)合“部首目錄”和“檢字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“張”字,我們可以看到在查部首之后的檢字表中“張”的頁碼是672頁,檢字表中“張”的上面是“馳”字,但頁碼卻是63頁,“張”的下面是“弩”字,頁面是390頁。很顯然,這些字并不是真正的分別位于“張”字的上下方,現(xiàn)在您看到的連續(xù)的“馳、張、弩”三字實際上就是他們在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我們可以通過這種方式來找到您所需要的字,但它需要兩個過程,先找到目錄中的結(jié)果,然后再翻到您所需要的頁碼。

我們把這種目錄純粹是目錄,正文純粹是正文的排序方式稱為“非聚集索引”。

通過以上例子,我們可以理解到什么是“聚集索引”和“非聚集索引”。

進一步引申一下,我們可以很容易的理解:每個表只能有一個聚集索引,因為目錄只能按照一種方法進行排序。

(二)何時使用聚集索引或非聚集索引

下面的表總結(jié)了何時使用聚集索引或非聚集索引(很重要)。

動作描述

使用聚集索引

使用非聚集索引

列經(jīng)常被分組排序

應(yīng)

應(yīng)

返回某范圍內(nèi)的數(shù)據(jù)

應(yīng)

不應(yīng)

一個或極少不同值

不應(yīng)

不應(yīng)

小數(shù)目的不同值

應(yīng)

不應(yīng)

大數(shù)目的不同值

不應(yīng)

應(yīng)

頻繁更新的列

不應(yīng)

應(yīng)

外鍵列

應(yīng)

應(yīng)

主鍵列

應(yīng)

應(yīng)

頻繁修改索引列

不應(yīng)

應(yīng)

事實上,我們可以通過前面聚集索引和非聚集索引的定義的例子來理解上表。如:返回某范圍內(nèi)的數(shù)據(jù)一項。比如您的某個表有一個時間列,恰好您把聚合索引建立在了該列,這時您查詢2004112004101之間的全部數(shù)據(jù)時,這個速度就將是很快的,因為您的這本字典正文是按日期進行排序的,聚類索引只需要找到要檢索的所有數(shù)據(jù)中的開頭和結(jié)尾數(shù)據(jù)即可;而不像非聚集索引,必須先查到目錄中查到每一項數(shù)據(jù)對應(yīng)的頁碼,然后再根據(jù)頁碼查到具體內(nèi)容。

(三)結(jié)合實際,談索引使用的誤區(qū)

理論的目的是應(yīng)用。雖然我們剛才列出了何時應(yīng)使用聚集索引或非聚集索引,但在實踐中以上規(guī)則卻很容易被忽視或不能根據(jù)實際情況進行綜合分析。下面我們將根據(jù)在實踐中遇到的實際問題來談一下索引使用的誤區(qū),以便于大家掌握索引建立的方法。

1、主鍵就是聚集索引

這種想法筆者認為是極端錯誤的,是對聚集索引的一種浪費。雖然SQL SERVER默認是在主鍵上建立聚集索引的。

通常,我們會在每個表中都建立一個ID列,以區(qū)分每條數(shù)據(jù),并且這個ID列是自動增大的,步長一般為1。我們的這個辦公自動化的實例中的列Gid就是如此。此時,如果我們將這個列設(shè)為主鍵,SQL SERVER會將此列默認為聚集索引。這樣做有好處,就是可以讓您的數(shù)據(jù)在數(shù)據(jù)庫中按照ID進行物理排序,但筆者認為這樣做意義不大。

顯而易見,聚集索引的優(yōu)勢是很明顯的,而每個表中只能有一個聚集索引的規(guī)則,這使得聚集索引變得更加珍貴。

從我們前面談到的聚集索引的定義我們可以看出,使用聚集索引的最大好處就是能夠根據(jù)查詢要求,迅速縮小查詢范圍,避免全表掃描。在實際應(yīng)用中,因為ID號是自動生成的,我們并不知道每條記錄的ID號,所以我們很難在實踐中用ID號來進行查詢。這就使讓ID號這個主鍵作為聚集索引成為一種資源浪費。其次,讓每個ID號都不同的字段作為聚集索引也不符合“大數(shù)目的不同值情況下不應(yīng)建立聚合索引”規(guī)則;當(dāng)然,這種情況只是針對用戶經(jīng)常修改記錄內(nèi)容,特別是索引項的時候會負作用,但對于查詢速度并沒有影響。

在辦公自動化系統(tǒng)中,無論是系統(tǒng)首頁顯示的需要用戶簽收的文件、會議還是用戶進行文件查詢等任何情況下進行數(shù)據(jù)查詢都離不開字段的是“日期”還有用戶本身的“用戶名”。

通常,辦公自動化的首頁會顯示每個用戶尚未簽收的文件或會議。雖然我們的where語句可以僅僅限制當(dāng)前用戶尚未簽收的情況,但如果您的系統(tǒng)已建立了很長時間,并且數(shù)據(jù)量很大,那么,每次每個用戶打開首頁的時候都進行一次全表掃描,這樣做意義是不大的,絕大多數(shù)的用戶1個月前的文件都已經(jīng)瀏覽過了,這樣做只能徒增數(shù)據(jù)庫的開銷而已。事實上,我們完全可以讓用戶打開系統(tǒng)首頁時,數(shù)據(jù)庫僅僅查詢這個用戶近3個月來未閱覽的文件,通過“日期”這個字段來限制表掃描,提高查詢速度。如果您的辦公自動化系統(tǒng)已經(jīng)建立的2年,那么您的首頁顯示速度理論上將是原來速度8倍,甚至更快。

在這里之所以提到“理論上”三字,是因為如果您的聚集索引還是盲目地建在ID這個主鍵上時,您的查詢速度是沒有這么高的,即使您在“日期”這個字段上建立的索引(非聚合索引)。下面我們就來看一下在1000萬條數(shù)據(jù)量的情況下各種查詢的速度表現(xiàn)(3個月內(nèi)的數(shù)據(jù)為25萬條):

1)僅在主鍵上建立聚集索引,并且不劃分時間段:

Select gid,fariqi,neibuyonghu,title from tgongwen

用時:128470毫秒(即:128秒)

2)在主鍵上建立聚集索引,在fariq上建立非聚集索引:

selectgid,fariqi,neibuyonghu,titlefromTgongwen
wherefariqi>dateadd(day,-90,getdate())

用時:53763毫秒(54秒)

3)將聚合索引建立在日期列(fariqi)上:

selectgid,fariqi,neibuyonghu,titlefromTgongwen
wherefariqi>dateadd(day,-90,getdate())

用時:2423毫秒(2秒)

雖然每條語句提取出來的都是25萬條數(shù)據(jù),各種情況的差異卻是巨大的,特別是將聚集索引建立在日期列時的差異。事實上,如果您的數(shù)據(jù)庫真的有1000萬容量的話,把主鍵建立在ID列上,就像以上的第1、2種情況,在網(wǎng)頁上的表現(xiàn)就是超時,根本就無法顯示。這也是我摒棄ID列作為聚集索引的一個最重要的因素。

得出以上速度的方法是:在各個select語句前加:declare @d datetime

set @d=getdate()

并在select語句后加:

select [語句執(zhí)行花費時間(毫秒)]=datediff(ms,@d,getdate())

2、只要建立索引就能顯著提高查詢速度

事實上,我們可以發(fā)現(xiàn)上面的例子中,第23條語句完全相同,且建立索引的字段也相同;不同的僅是前者在fariqi字段上建立的是非聚合索引,后者在此字段上建立的是聚合索引,但查詢速度卻有著天壤之別。所以,并非是在任何字段上簡單地建立索引就能提高查詢速度。

從建表的語句中,我們可以看到這個有著1000萬數(shù)據(jù)的表中fariqi字段有5003個不同記錄。在此字段上建立聚合索引是再合適不過了。在現(xiàn)實中,我們每天都會發(fā)幾個文件,這幾個文件的發(fā)文日期就相同,這完全符合建立聚集索引要求的:“既不能絕大多數(shù)都相同,又不能只有極少數(shù)相同”的規(guī)則。由此看來,我們建立“適當(dāng)”的聚合索引對于我們提高查詢速度是非常重要的。

3、把所有需要提高查詢速度的字段都加進聚集索引,以提高查詢速度

上面已經(jīng)談到:在進行數(shù)據(jù)查詢時都離不開字段的是“日期”還有用戶本身的“用戶名”。既然這兩個字段都是如此的重要,我們可以把他們合并起來,建立一個復(fù)合索引(compound index)。

很多人認為只要把任何字段加進聚集索引,就能提高查詢速度,也有人感到迷惑:如果把復(fù)合的聚集索引字段分開查詢,那么查詢速度會減慢嗎?帶著這個問題,我們來看一下以下的查詢速度(結(jié)果集都是25萬條數(shù)據(jù)):(日期列fariqi首先排在復(fù)合聚集索引的起始列,用戶名neibuyonghu排在后列)

1select gid,fariqi,neibuyonghu,title from Tgongwen where fariqi>'2004-5-5'

查詢速度:2513毫秒

2select gid,fariqi,neibuyonghu,title from Tgongwen where fariqi>'2004-5-5' and neibuyonghu='辦公室'

查詢速度:2516毫秒

3select gid,fariqi,neibuyonghu,title from Tgongwen where neibuyonghu='辦公室'

查詢速度:60280毫秒

從以上試驗中,我們可以看到如果僅用聚集索引的起始列作為查詢條件和同時用到復(fù)合聚集索引的全部列的查詢速度是幾乎一樣的,甚至比用上全部的復(fù)合索引列還要略快(在查詢結(jié)果集數(shù)目一樣的情況下);而如果僅用復(fù)合聚集索引的非起始列作為查詢條件的話,這個索引是不起任何作用的。當(dāng)然,語句1、2的查詢速度一樣是因為查詢的條目數(shù)一樣,如果復(fù)合索引的所有列都用上,而且查詢結(jié)果少的話,這樣就會形成“索引覆蓋”,因而性能可以達到最優(yōu)。同時,請記?。簾o論您是否經(jīng)常使用聚合索引的其他列,但其前導(dǎo)列一定要是使用最頻繁的列。

(四)其他書上沒有的索引使用經(jīng)驗總結(jié)

1、用聚合索引比用不是聚合索引的主鍵速度快

下面是實例語句:(都是提取25萬條數(shù)據(jù))

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時速度快,特別是在小數(shù)據(jù)量情況下

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。事實上,如果數(shù)據(jù)量很小的話,用聚集索引作為排序列要比使用非聚集索引速度快得明顯的多;而數(shù)據(jù)量如果很大的話,如10萬以上,則二者的速度差別不明顯。

3、使用聚合索引內(nèi)的時間段,搜索時間會按數(shù)據(jù)占整個數(shù)據(jù)表的百分比成比例減少,而無論聚合索引使用了多少個

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毫秒(和上句的結(jié)果一模一樣。如果采集的數(shù)量一樣,那么用大于號和等于號是一樣的)

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi>'2004-1-1' and fariqi<'2004-6-6'

用時:3280毫秒

4 、日期列不會因為有分秒的輸入而減慢查詢速度

下面的例子中,共有100萬條數(shù)據(jù),200411以后的數(shù)據(jù)有50萬條,但只有兩個不同的日期,日期精確到日;之前有數(shù)據(jù)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毫秒

(五)其他注意事項

“水可載舟,亦可覆舟”,索引也一樣。索引有助于提高檢索性能,但過多或不當(dāng)?shù)乃饕矔?dǎo)致系統(tǒng)低效。因為用戶在表中每加進一個索引,數(shù)據(jù)庫就要做更多的工作。過多的索引甚至?xí)?dǎo)致索引碎片。

所以說,我們要建立一個“適當(dāng)”的索引體系,特別是對聚合索引的創(chuàng)建,更應(yīng)精益求精,以使您的數(shù)據(jù)庫能得到高性能的發(fā)揮。

當(dāng)然,在實踐中,作為一個盡職的數(shù)據(jù)庫管理員,您還要多測試一些方案,找出哪種方案效率最高、最為有效。

二、改善SQL語句

很多人不知道SQL語句在SQL SERVER中是如何執(zhí)行的,他們擔(dān)心自己所寫的SQL語句會被SQL SERVER誤解。比如:

select * from table1 where name='zhangsan' and tID > 10000

和執(zhí)行:

select * from table1 where tID > 10000 and name='zhangsan'

一些人不知道以上兩條語句的執(zhí)行效率是否一樣,因為如果簡單的從語句先后上看,這兩個語句的確是不一樣,如果tID是一個聚合索引,那么后一句僅僅從表的10000條以后的記錄中查找就行了;而前一句則要先從全表中查找看有幾個name='zhangsan'的,而后再根據(jù)限制條件條件tID>10000來提出查詢結(jié)果。

事實上,這樣的擔(dān)心是不必要的。SQL SERVER中有一個“查詢分析優(yōu)化器”,它可以計算出where子句中的搜索條件并確定哪個索引能縮小表掃描的搜索空間,也就是說,它能實現(xiàn)自動優(yōu)化。

雖然查詢優(yōu)化器可以根據(jù)where子句自動的進行查詢優(yōu)化,但大家仍然有必要了解一下“查詢優(yōu)化器”的工作原理,如非這樣,有時查詢優(yōu)化器就會不按照您的本意進行快速查詢。

在查詢分析階段,查詢優(yōu)化器查看查詢的每個階段并決定限制需要掃描的數(shù)據(jù)量是否有用。如果一個階段可以被用作一個掃描參數(shù)(SARG),那么就稱之為可優(yōu)化的,并且可以利用索引快速獲得所需數(shù)據(jù)。

SARG的定義:用于限制搜索的一個操作,因為它通常是指一個特定的匹配,一個值得范圍內(nèi)的匹配或者兩個以上條件的AND連接。形式如下:

列名 操作符 <常數(shù) 變量>

<常數(shù) 變量> 操作符列名

列名可以出現(xiàn)在操作符的一邊,而常數(shù)或變量出現(xiàn)在操作符的另一邊。如:

Name='張三'

價格>5000

5000<價格

Name='張三' and 價格>5000

如果一個表達式不能滿足SARG的形式,那它就無法限制搜索的范圍了,也就是SQL SERVER必須對每一行都判斷它是否滿足WHERE子句中的所有條件。所以一個索引對于不滿足SARG形式的表達式來說是無用的。

介紹完SARG后,我們來總結(jié)一下使用SARG以及在實踐中遇到的和某些資料上結(jié)論不同的經(jīng)驗:

1、Like語句是否屬于SARG取決于所使用的通配符的類型

如:name like ‘張%' ,這就屬于SARG

而:name like %張' ,就不屬于SARG

原因是通配符%在字符串的開通使得索引無法使用。

2、or 會引起全表掃描

Name='張三' and 價格>5000 符號SARG,而:Name='張三' or 價格>5000 則不符合SARG。使用or會引起全表掃描。

3、非操作符、函數(shù)引起的不滿足SARG形式的語句

不滿足SARG形式的語句最典型的情況就是包括非操作符的語句,如:NOT、!=、<>、!<!>、NOT EXISTS、NOT INNOT LIKE等,另外還有函數(shù)。下面就是幾個不滿足SARG形式的例子:

ABS(價格)<5000

Name like %三'

有些表達式,如:

WHERE 價格*2>5000

SQL SERVER也會認為是SARG,SQL SERVER會將此式轉(zhuǎn)化為:

WHERE 價格>2500/2

但我們不推薦這樣使用,因為有時SQL SERVER不能保證這種轉(zhuǎn)化與原始表達式是完全等價的。

4IN 的作用相當(dāng)與OR

語句:

Select * from table1 where tid in (2,3)

Select * from table1 where tid=2 or tid=3

是一樣的,都會引起全表掃描,如果tid上有索引,其索引也會失效。

5、盡量少用NOT

6、exists in 的執(zhí)行效率是一樣的

很多資料上都顯示說,exists要比in的執(zhí)行效率要高,同時應(yīng)盡可能的用not exists來代替not in。但事實上,我試驗了一下,發(fā)現(xiàn)二者無論是前面帶不帶not,二者之間的執(zhí)行效率都是一樣的。因為涉及子查詢,我們試驗這次用SQL SERVER自帶的pubs數(shù)據(jù)庫。運行前我們可以把SQL SERVERstatistics I/O狀態(tài)打開。

1select title,price from titles where title_id in (select title_id from sales where qty>30)

該句的執(zhí)行結(jié)果為:

'sales'。掃描計數(shù) 18,邏輯讀 56 次,物理讀 0 次,預(yù)讀 0 次。

'titles'。掃描計數(shù) 1,邏輯讀 2 次,物理讀 0 次,預(yù)讀 0 次。

2select title,price from titles where exists (select * from sales where sales.title_id=titles.title_id and qty>30)

第二句的執(zhí)行結(jié)果為:

'sales'。掃描計數(shù) 18,邏輯讀 56 次,物理讀 0 次,預(yù)讀 0 次。

'titles'。掃描計數(shù) 1,邏輯讀 2 次,物理讀 0 次,預(yù)讀 0 次。

我們從此可以看到用exists和用in的執(zhí)行效率是一樣的。

7、用函數(shù)charindex()和前面加通配符%LIKE執(zhí)行效率一樣

前面,我們談到,如果在LIKE前面加上通配符%,那么將會引起全表掃描,所以其執(zhí)行效率是低下的。但有的資料介紹說,用函數(shù)charindex()來代替LIKE速度會有大的提升,經(jīng)我試驗,發(fā)現(xiàn)這種說明也是錯誤的:

select gid,title,fariqi,reader from tgongwen where charindex('刑偵支隊',reader)>0 and fariqi>'2004-5-5'

用時:7秒,另外:掃描計數(shù) 4,邏輯讀 7155 次,物理讀 0 次,預(yù)讀 0 次。

select gid,title,fariqi,reader from tgongwen where reader like '%' + '刑偵支隊' + '%' and fariqi>'2004-5-5'

用時:7秒,另外:掃描計數(shù) 4,邏輯讀 7155 次,物理讀 0 次,預(yù)讀 0 次。

8union并不絕對比or的執(zhí)行效率高

我們前面已經(jīng)談到了在where子句中使用or會引起全表掃描,一般的,我所見過的資料都是推薦這里用union來代替or。事實證明,這種說法對于大部分都是適用的。

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi='2004-9-16' or gid>9990000

用時:68秒。掃描計數(shù) 1,邏輯讀 404008 次,物理讀 283 次,預(yù)讀 392163 次。

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi='2004-9-16'

union

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where gid>9990000

用時:9秒。掃描計數(shù) 8,邏輯讀 67489 次,物理讀 216 次,預(yù)讀 7499 次。

看來,用union在通常情況下比用or的效率要高的多。

但經(jīng)過試驗,筆者發(fā)現(xiàn)如果or兩邊的查詢列是一樣的話,那么用union則反倒和用or的執(zhí)行速度差很多,雖然這里union掃描的是索引,而or掃描的是全表。

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi='2004-9-16' or fariqi='2004-2-5'

用時:6423毫秒。掃描計數(shù) 2,邏輯讀 14726 次,物理讀 1 次,預(yù)讀 7176 次。

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi='2004-9-16'

union

select gid,fariqi,neibuyonghu,reader,title from Tgongwen wherefariqi='2004-2-5'

用時:11640毫秒。掃描計數(shù) 8,邏輯讀 14806 次,物理讀 108 次,預(yù)讀 1144 次。

9、字段提取要按照“需多少、提多少”的原則,避免“select *

我們來做一個試驗:

select top 10000 gid,fariqi,reader,title from tgongwen order by gid desc

用時:4673毫秒

select top 10000 gid,fariqi,title from tgongwen order by gid desc

用時:1376毫秒

select top 10000 gid,fariqi from tgongwen order by gid desc

用時:80毫秒

由此看來,我們每少提取一個字段,數(shù)據(jù)的提取速度就會有相應(yīng)的提升。提升的速度還要看您舍棄的字段的大小來判斷。

10、count(*)不比count(字段)

某些資料上說:用*會統(tǒng)計所有列,顯然要比一個世界的列名效率低。這種說法其實是沒有根據(jù)的。我們來看:

select count(*) from Tgongwen

用時:1500毫秒

select count(gid) from Tgongwen

用時:1483毫秒

select count(fariqi) from Tgongwen

用時:3140毫秒

select count(title) from Tgongwen

用時:52050毫秒

從以上可以看出,如果用count(*)和用count(主鍵)的速度是相當(dāng)?shù)?,?/SPAN>count(*)卻比其他任何除主鍵以外的字段匯總速度要快,而且字段越長,匯總的速度就越慢。我想,如果用count(*) SQL SERVER可能會自動查找最小字段來匯總的。當(dāng)然,如果您直接寫count(主鍵)將會來的更直接些。

11、order by按聚集索引列排序效率最高

我們來看:(gid是主鍵,fariqi是聚合索引列)

select top 10000 gid,fariqi,reader,title from tgongwen

用時:196 毫秒。 掃描計數(shù) 1,邏輯讀 289 次,物理讀 1 次,預(yù)讀 1527 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by gid asc

用時:4720毫秒。 掃描計數(shù) 1,邏輯讀 41956 次,物理讀 0 次,預(yù)讀 1287 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by gid desc

用時:4736毫秒。 掃描計數(shù) 1,邏輯讀 55350 次,物理讀 10 次,預(yù)讀 775 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by fariqi asc

用時:173毫秒。 掃描計數(shù) 1,邏輯讀 290 次,物理讀 0 次,預(yù)讀 0 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by fariqi desc

用時:156毫秒。 掃描計數(shù) 1,邏輯讀 289 次,物理讀 0 次,預(yù)讀 0 次。

從以上我們可以看出,不排序的速度以及邏輯讀次數(shù)都是和“order by 聚集索引列” 的速度是相當(dāng)?shù)?,但這些都比“order by 非聚集索引列”的查詢速度是快得多的。

同時,按照某個字段進行排序的時候,無論是正序還是倒序,速度是基本相當(dāng)?shù)摹?/SPAN>

12、高效的TOP

事實上,在查詢和提取超大容量的數(shù)據(jù)集時,影響數(shù)據(jù)庫響應(yīng)時間的最大因素不是數(shù)據(jù)查找,而是物理的I/0操作。如:

select top 10 * from (

select top 10000 gid,fariqi,title from tgongwen

where

版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部