免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
SQLSERVER2008R2 索引建立的幾點(diǎn)建議

1、不要把聚集索引浪費(fèi)在主鍵上,除非你只按主鍵查詢

       雖然SQL SERVER默認(rèn)是在主鍵上建立聚集索引的,但實(shí)際應(yīng)用中,這樣做比較浪費(fèi)。通常,我們會(huì)在每個(gè)表中都建立一個(gè)ID列,以區(qū)分每條數(shù)據(jù),并且這個(gè)ID列是自動(dòng)增大的,步長(zhǎng)一般為1。此時(shí),如果我們將這個(gè)列設(shè)為主鍵,SQL SERVER會(huì)將此列默認(rèn)為聚集索引。這樣做有好處,就是可以讓您的數(shù)據(jù)在數(shù)據(jù)庫(kù)中按照ID進(jìn)行物理排序,但這樣做實(shí)用價(jià)值不大。

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

2、索引的建立要根據(jù)實(shí)際應(yīng)用需求來進(jìn)行

       并非是在任何字段上簡(jiǎn)單地建立索引就能提高查詢速度。聚集索引建立的規(guī)則大致是“既不能絕大多數(shù)都相同,又不能只有極少數(shù)相同”。舉個(gè)例子,在公文表的收發(fā)日期字段上建立聚合索引是比較合適的。在政務(wù)系統(tǒng)中,我們每天都會(huì)收一些文件,這些文件的發(fā)文日期將會(huì)相同,在發(fā)文日期上建立聚合索引對(duì)性能的提升應(yīng)該是相當(dāng)大的。在群集索引下,數(shù)據(jù)物理上按順序存于數(shù)據(jù)頁上,重復(fù)值也排列在一起,因而在范圍查找時(shí),可以先找到這個(gè)范圍的起末點(diǎn),且只在這個(gè)范圍內(nèi)掃描數(shù)據(jù)頁,避免了大范圍掃描,提高了查詢速度。

另一個(gè)相反的例子:比如在雇員表的“性別”列上只有“男”與“女”兩個(gè)不同值,因此就完全沒必要建立索引。

3、在聚集索引中加入所有需要提高查詢速度的字段,形成復(fù)合索引

       根據(jù)一些實(shí)驗(yàn)的結(jié)果,我們可以得出一些可供參考的結(jié)論:

       僅用復(fù)合聚集索引的起始列作為查詢條件和同時(shí)用到復(fù)合聚集索引的全部列的查詢,速度是幾乎一樣的,甚至比后者還要快(在查詢結(jié)果集數(shù)目一樣的情況下);

       僅用復(fù)合聚集索引的非起始列作為查詢條件的話,

       這個(gè)索引是不起任何作用的。

       復(fù)合聚集索引的所有列都用上,而且因?yàn)椴樵儣l件嚴(yán)格,查詢結(jié)果少的話,會(huì)形成“索引覆蓋”,性能可以達(dá)到最優(yōu)。

       最重要的一點(diǎn):無論是否經(jīng)常使用復(fù)合聚合索引的其他列,其起始列一定要是使用最頻繁的列。

4.根據(jù)實(shí)踐得出的一些其他經(jīng)驗(yàn),特定情況下有效

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

       用聚合索引比用一般的主鍵作order by速度快,特別是在小數(shù)據(jù)量情況;

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

       日期列不會(huì)因?yàn)橛蟹置氲妮斎攵鴾p慢查詢速度;

       由于改變一個(gè)表的內(nèi)容,將會(huì)引起索引的變化。頻繁的insert,update,delete語句將導(dǎo)致系統(tǒng)花費(fèi)較大的代價(jià)進(jìn)行索引更新,引起整體性能的下降。一般來講,在對(duì)查詢性能的要求高于對(duì)數(shù)據(jù)維護(hù)性能要求時(shí),應(yīng)該盡量使用索引,否則,就要慎重考慮一下付出的代價(jià)。在某些極端情況下,可先刪除索引,再對(duì)數(shù)據(jù)庫(kù)表更新大量數(shù)據(jù),最后再重建索引,新建立的索引總是比較好用。

SQLSERVER2008R2正確使用索引

T1表 10000000萬條數(shù)據(jù),(插入時(shí)間36分鐘,count(*)查詢19秒,空間占用670M左右)

 

1.真正充分的利用索引
比如like '張%' 就是符合SARG(符合掃描參數(shù))標(biāo)準(zhǔn)
而like '%張' 就不符合該標(biāo)準(zhǔn)

通配符%在字符串首字符的使用會(huì)導(dǎo)致索引無法使用,雖然實(shí)際應(yīng)用中很難避免這樣用,但還是應(yīng)該對(duì)這種現(xiàn)象有所了解,至少知道此種用法性能是很低下的。

 

**********************************************


2.“非”操作符不滿足SARG形式,使得索引無法使用
不滿足SARG形式的語句最典型的情況就是包括非操作符的語句,如:NOT、!=、<>、!<、!>、NOT EXISTS、NOT IN、NOT LIKE等。
如果使用not 或者 <>,最好轉(zhuǎn)換成別的方法,比如例子如下:

T1表 10000000萬條數(shù)據(jù),構(gòu)建如下:(插入時(shí)間36分鐘,count(*)查詢19秒,空間占用670M左右)

DECLARE @i INT
SET @i = 1
WHILE @i<1000000
BEGIN
 INSERT INTO t1 VALUES ('zhang'+CONVERT(char(50), @i),'3.2',77);
 SET @i + 1;
END

三種查詢方式:

SELECT * FROM t1 WHERE id <>300000
SELECT * FROM t1 WHERE id NOT IN (300000)
SELECT * FROM t1 WHERE id >299999 AND id < 300001

在執(zhí)行計(jì)劃中可以明顯看出,使用最后一種方式而不是前面兩種方式進(jìn)行查詢。
網(wǎng)上是這么說的,但自己做的試驗(yàn)100W條數(shù)據(jù),開銷計(jì)劃是一樣的。

 

*********************************************

 

3. 函數(shù)運(yùn)算不滿足SARG形式,使得索引無法使用
例:下列SQL條件語句中的列都建有恰當(dāng)?shù)乃饕珗?zhí)行速度卻非常慢:

select * from record where substring(card_no,1,4)=′5378′(13秒)
select * from record where amount/30< 1000(11秒)
select * from record where convert(char(10),date,112)=′19991201′(10秒)

分析:

where子句中對(duì)列的任何操作結(jié)果都是在SQL運(yùn)行時(shí)逐列計(jì)算得到的,因此它不得不進(jìn)行全表掃描,而沒有使用該列上面的索引;如果這些結(jié)果在查詢編譯時(shí)就能得到,那么就可以被SQL優(yōu)化器優(yōu)化,使用索引,避免表搜索,因此將SQL重寫成下面這樣:

select * from record where card_no like ′5378%′(< 1秒)
select * from record where amount < 1000*30(< 1秒)
select * from record where date= ′1999/12/01′ (< 1秒)

你會(huì)發(fā)現(xiàn)SQL明顯快很多

待測(cè)試.......

 

**********************************************

 

4.盡量不要對(duì)建立了索引的字段,作任何的直接處理

select * from employs where first_name + last_name ='beill cliton';

無法使用索引,改為:

select * from employee where
first_name = substr('beill cliton',1,instr('beill cliton',' ')-1)
and
last_name = substr('beill cliton',instr('beill cliton',' ')+1)

則可以使用索引


***********************************************


5.不同類型的索引效能是不一樣的,應(yīng)盡可能先使用效能高的
比如:數(shù)字類型的索引查找效率高于字符串類型,定長(zhǎng)字符串char,nchar的索引效率高于變長(zhǎng)字符串varchar,nvarchar的索引。
應(yīng)該將
where username='張三' and age>20
改進(jìn)為
where age>20 and username='張三'
注意:此處,SQL的查詢分析優(yōu)化功能可以做到自動(dòng)重排條件順序,但還是建議預(yù)先手工排列好。


**************************************************


6.某些情況下IN 的作用與OR 相當(dāng) ,且都不能充分利用索引
例:表stuff有200000行,id_no上有非群集索引,請(qǐng)看下面這個(gè)SQL:
select count(*) from stuff where id_no in(′0′,′1′) (23秒)
我們期望它會(huì)根據(jù)每個(gè)or子句分別查找,再將結(jié)果相加,這樣可以利用id_no上的索引;但實(shí)際上,它卻采用了"OR策略",即先取出滿足每個(gè)or子句的行,存入臨時(shí)數(shù)據(jù)庫(kù)的工作表中,再建立唯一索引以去掉重復(fù)行,最后從這個(gè)臨時(shí)表中計(jì)算結(jié)果。因此,實(shí)際過程沒有利用id_no 上索引,并且完成時(shí)間還要受tempdb數(shù)據(jù)庫(kù)性能的影響。
實(shí)踐證明,表的行數(shù)越多,工作表的性能就越差,當(dāng)stuff有620000行時(shí),執(zhí)行時(shí)間會(huì)非常長(zhǎng)!如果確定不同的條件不會(huì)產(chǎn)生大量重復(fù)值,還不如將or子句分開:

select count(*) from stuff where id_no=′0′
select count(*) from stuff where id_no=′1′

得到兩個(gè)結(jié)果,再用union作一次加法合算。因?yàn)槊烤涠际褂昧怂饕?,?zhí)行時(shí)間會(huì)比較短,

select count(*) from stuff where id_no=′0′
union
select count(*) from stuff where id_no=′1′

從實(shí)踐效果來看,使用union在通常情況下比用or的效率要高的多,而exist關(guān)鍵字和in關(guān)鍵字在用法上類似,性能上也類似,都會(huì)產(chǎn)生全表掃描,效率比較低下,根據(jù)未經(jīng)驗(yàn)證的說法,exist可能比in要快些。


***************************************************


7.使用變通的方法提高查詢效率

  like關(guān)鍵字支持通配符匹配,但這種匹配特別耗時(shí)。例如:select * from customer where zipcode like “21_ _ _”,即使在zipcode字段上已建立了索引,在這種情況下也可能還是采用全表掃描方式。如果把語句改為:select * from customer where zipcode >“21000”,在執(zhí)行查詢時(shí)就會(huì)利用索引,大大提高速度。但這種變通是有限制的,不應(yīng)引起業(yè)務(wù)意義上的損失,對(duì)于郵政編碼而言,zipcode like “21_ _ _” 和 zipcode >“21000” 意義是完全一致的。


*********************************************************人各有志,但富貴在天,人生允許彷徨,但不允許蹉跎.

 

8.order by按聚集索引列排序效率最高
排序是較耗時(shí)的操作,應(yīng)盡量簡(jiǎn)化或避免對(duì)大型表進(jìn)行排序,如縮小排序的列的范圍,只在有索引的列上排序等等。
我們來看:(gid是主鍵,fariqi是聚合索引列)
select top 10000 gid,fariqi,reader,title from tgongwen
用時(shí):196 毫秒。 掃描計(jì)數(shù) 1,邏輯讀 289 次,物理讀 1 次,預(yù)讀 1527 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by gid asc
用時(shí):4720毫秒。 掃描計(jì)數(shù) 1,邏輯讀 41956 次,物理讀 0 次,預(yù)讀 1287 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by gid desc
用時(shí):4736毫秒。 掃描計(jì)數(shù) 1,邏輯讀 55350 次,物理讀 10 次,預(yù)讀 775 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by fariqi asc
用時(shí):173毫秒。 掃描計(jì)數(shù) 1,邏輯讀 290 次,物理讀 0 次,預(yù)讀 0 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by fariqi desc
用時(shí):156毫秒。 掃描計(jì)數(shù) 1,邏輯讀 289 次,物理讀 0 次,預(yù)讀 0 次。

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

 

********************************************************


9.關(guān)于節(jié)省數(shù)據(jù)查詢系統(tǒng)開銷方面的措施
 (1)使用TOP盡量減少取出的數(shù)據(jù)量
 (2)字段提取要按照“需多少、提多少”的原則,避免“select *”
字段大小越大,數(shù)目越多,select所耗費(fèi)的資源就越多,比如取int類型的字段就會(huì)比取char的快很多。我們每少提取一個(gè)字段,數(shù)據(jù)的提取速度就會(huì)有相應(yīng)的提升。提升的幅度根據(jù)舍棄的字段的大小來判斷
 (3)count(*) 與 count(字段) 方法比較
 用count(*)和用 count(主鍵)的速度是相當(dāng)?shù)?,而count(*)卻比其他任何除主鍵以外的字段匯總速度要快,而且字段越長(zhǎng),匯總速度就越慢。如果用 count(*), SQL SERVER會(huì)自動(dòng)查找最小字段來匯總。當(dāng)然,如果您直接寫count(主鍵)將會(huì)來的更直接些
 (4)有嵌套查詢時(shí),盡可能在內(nèi)層過濾掉數(shù)據(jù)
 如果一個(gè)列同時(shí)在主查詢和where子句中出現(xiàn),很可能當(dāng)主查詢中的列值改變之后,子查詢必須重新查詢一次。而且查詢嵌套層次越多,效率越低,因此應(yīng)當(dāng)盡量避免子查詢。如果子查詢不可避免,那么要在子查詢中過濾掉盡可能多的行
 (5)多表關(guān)聯(lián)查詢時(shí),需注意表順序,并盡可能早的過濾掉數(shù)據(jù)
 在使用Join進(jìn)行多表關(guān)聯(lián)查詢時(shí)候,應(yīng)該使用系統(tǒng)開銷最小的方案。連接條件要充份考慮帶有索引的表、行數(shù)多的表,并注意優(yōu)化表順序;說的簡(jiǎn)單一點(diǎn),就是盡可能早的將之后要做關(guān)聯(lián)的數(shù)據(jù)量降下來。

 一般情況下,sqlserver 會(huì)對(duì)表的連接作出自動(dòng)優(yōu)化。例如:
 select name,no from A
 join B on A. id=B.id
 join C on C.id=A.id
 where name='wang'
        盡管A表在From中先列出,然后才是B,最后才是C。但sql server可能會(huì)首先使用c表。它的選擇原則是相對(duì)于該查詢限制為單行或少數(shù)幾行,就可以減少在其他表中查找的總數(shù)據(jù)量。絕大多數(shù)情況下,sql server 會(huì)作出最優(yōu)的選擇,但如果你發(fā)覺某個(gè)復(fù)雜的聯(lián)結(jié)查詢速度比預(yù)計(jì)的要慢,就可以使用SET FORCEPLAN語句強(qiáng)制sql server按照表出現(xiàn)順序使用表。如上例加上:SET FORCEPLAN ON…….SET FORCEPLAN OFF 表的執(zhí)行順序?qū)?huì)按照你所寫的順序執(zhí)行。在查詢分析器中查看2種執(zhí)行效率,從而選擇表的連接順序。SET FORCEPLAN的缺點(diǎn)是只能在存儲(chǔ)過程中使用

PS:數(shù)據(jù)庫(kù)的查詢優(yōu)化技術(shù) 
 
數(shù)據(jù)庫(kù)系統(tǒng)是管理信息系統(tǒng)的核心,基于數(shù)據(jù)庫(kù)的聯(lián)機(jī)事務(wù)處理(OLTP)以及聯(lián)機(jī)分析處理(OLAP)是銀行、企業(yè)、政府等部門最為重要的計(jì)算機(jī)應(yīng)用之一。從大多數(shù)系統(tǒng)的應(yīng)用實(shí)例來看,查詢操作在各種數(shù)據(jù)庫(kù)操作中所占據(jù)的比重最大,而查詢操作所基于的SELECT語句在SQL語句中又是代價(jià)最大的語句。舉例來說,如果數(shù)據(jù)的量積累到一定的程度,比如一個(gè)銀行的賬戶數(shù)據(jù)庫(kù)表信息積累到上百萬甚至上千萬條記錄,全表掃描一次往往需要數(shù)十分鐘,甚至數(shù)小時(shí)。如果采用比全表掃描更好的查詢策略,往往可以使查詢時(shí)間降為幾分鐘,由此可見查詢優(yōu)化技術(shù)的重要性。 
筆者在應(yīng)用項(xiàng)目的實(shí)施中發(fā)現(xiàn),許多程序員在利用一些前端數(shù)據(jù)庫(kù)開發(fā)工具(如PowerBuilder、Delphi等)開發(fā)數(shù)據(jù)庫(kù)應(yīng)用程序時(shí),只注重用戶界面的華麗,并不重視查詢語句的效率問題,導(dǎo)致所開發(fā)出來的應(yīng)用系統(tǒng)效率低下,資源浪費(fèi)嚴(yán)重。因此,如何設(shè)計(jì)高效合理的查詢語句就顯得非常重要。本文以應(yīng)用實(shí)例為基礎(chǔ),結(jié)合數(shù)據(jù)庫(kù)理論,介紹查詢優(yōu)化技術(shù)在現(xiàn)實(shí)系統(tǒng)中的運(yùn)用。 

分析問題 

許多程序員認(rèn)為查詢優(yōu)化是DBMS(數(shù)據(jù)庫(kù)管理系統(tǒng))的任務(wù),與程序員所編寫的SQL語句關(guān)系不大,這是錯(cuò)誤的。一個(gè)好的查詢計(jì)劃往往可以使程序性能提高數(shù)十倍。查詢計(jì)劃是用戶所提交的SQL語句的集合,查詢規(guī)劃是經(jīng)過優(yōu)化處理之后所產(chǎn)生的語句集合。DBMS處理查詢計(jì)劃的過程是這樣的:在做完查詢語句的詞法、語法檢查之后,將語句提交給DBMS的查詢優(yōu)化器,優(yōu)化器做完代數(shù)優(yōu)化和存取路徑的優(yōu)化之后,由預(yù)編譯模塊對(duì)語句進(jìn)行處理并生成查詢規(guī)劃,然后在合適的時(shí)間提交給系統(tǒng)處理執(zhí)行,最后將執(zhí)行結(jié)果返回給用戶。在實(shí)際的數(shù)據(jù)庫(kù)產(chǎn)品(如Oracle、Sybase等)的高版本中都是采用基于代價(jià)的優(yōu)化方法,這種優(yōu)化能根據(jù)從系統(tǒng)字典表所得到的信息來估計(jì)不同的查詢規(guī)劃的代價(jià),然后選擇一個(gè)較優(yōu)的規(guī)劃。雖然現(xiàn)在的數(shù)據(jù)庫(kù)產(chǎn)品在查詢優(yōu)化方面已經(jīng)做得越來越好,但由用戶提交的SQL語句是系統(tǒng)優(yōu)化的基礎(chǔ),很難設(shè)想一個(gè)原本糟糕的查詢計(jì)劃經(jīng)過系統(tǒng)的優(yōu)化之后會(huì)變得高效,因此用戶所寫語句的優(yōu)劣至關(guān)重要。系統(tǒng)所做查詢優(yōu)化我們暫不討論,下面重點(diǎn)說明改善用戶查詢計(jì)劃的解決方案。  
解決問題 
下面以關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)Informix為例,介紹改善用戶查詢計(jì)劃的方法。 

1.合理使用索引 
索引是數(shù)據(jù)庫(kù)中重要的數(shù)據(jù)結(jié)構(gòu),它的根本目的就是為了提高查詢效率?,F(xiàn)在大多數(shù)的數(shù)據(jù)庫(kù)產(chǎn)品都采用IBM最先提出的ISAM索引結(jié)構(gòu)。索引的使用要恰到好處,其使用原則如下: 
●在經(jīng)常進(jìn)行連接,但是沒有指定為外鍵的列上建立索引,而不經(jīng)常連接的字段則由優(yōu)化器自動(dòng)生成索引。 
●在頻繁進(jìn)行排序或分組(即進(jìn)行g(shù)roup by或order by操作)的列上建立索引。 
●在條件表達(dá)式中經(jīng)常用到的不同值較多的列上建立檢索,在不同值少的列上不要建立索引。比如在雇員表的“性別”列上只有“男”與“女”兩個(gè)不同值,因此就無必要建立索引。如果建立索引不但不會(huì)提高查詢效率,反而會(huì)嚴(yán)重降低更新速度。 
●如果待排序的列有多個(gè),可以在這些列上建立復(fù)合索引(compound index)。 
●使用系統(tǒng)工具。如Informix數(shù)據(jù)庫(kù)有一個(gè)tbcheck工具,可以在可疑的索引上進(jìn)行檢查。在一些數(shù)據(jù)庫(kù)服務(wù)器上,索引可能失效或者因?yàn)轭l繁操作而使得讀取效率降低,如果一個(gè)使用索引的查詢不明不白地慢下來,可以試著用tbcheck工具檢查索引的完整性,必要時(shí)進(jìn)行修復(fù)。另外,當(dāng)數(shù)據(jù)庫(kù)表更新大量數(shù)據(jù)后,刪除并重建索引可以提高查詢速度。 

2.避免或簡(jiǎn)化排序 
應(yīng)當(dāng)簡(jiǎn)化或避免對(duì)大型表進(jìn)行重復(fù)的排序。當(dāng)能夠利用索引自動(dòng)以適當(dāng)?shù)拇涡虍a(chǎn)生輸出時(shí),優(yōu)化器就避免了排序的步驟。以下是一些影響因素: 
●索引中不包括一個(gè)或幾個(gè)待排序的列; 
●group by或order by子句中列的次序與索引的次序不一樣; 
●排序的列來自不同的表。 
為了避免不必要的排序,就要正確地增建索引,合理地合并數(shù)據(jù)庫(kù)表(盡管有時(shí)可能影響表的規(guī)范化,但相對(duì)于效率的提高是值得的)。如果排序不可避免,那么應(yīng)當(dāng)試圖簡(jiǎn)化它,如縮小排序的列的范圍等。 

3.消除對(duì)大型表行數(shù)據(jù)的順序存取 
在嵌套查詢中,對(duì)表的順序存取對(duì)查詢效率可能產(chǎn)生致命的影響。比如采用順序存取策略,一個(gè)嵌套3層的查詢,如果每層都查詢1000行,那么這個(gè)查詢就要查詢10億行數(shù)據(jù)。避免這種情況的主要方法就是對(duì)連接的列進(jìn)行索引。例如,兩個(gè)表:學(xué)生表(學(xué)號(hào)、姓名、年齡……)和選課表(學(xué)號(hào)、課程號(hào)、成績(jī))。如果兩個(gè)表要做連接,就要在“學(xué)號(hào)”這個(gè)連接字段上建立索引。 
還可以使用并集來避免順序存取。盡管在所有的檢查列上都有索引,但某些形式的where子句強(qiáng)迫優(yōu)化器使用順序存取。下面的查詢將強(qiáng)迫對(duì)orders表執(zhí)行順序操作: 
SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008 
雖然在customer_num和order_num上建有索引,但是在上面的語句中優(yōu)化器還是使用順序存取路徑掃描整個(gè)表。因?yàn)檫@個(gè)語句要檢索的是分離的行的集合,所以應(yīng)該改為如下語句: 
SELECT * FROM orders WHERE customer_num=104 AND order_num>1001 
UNION 
SELECT * FROM orders WHERE order_num=1008 
這樣就能利用索引路徑處理查詢。 

4.避免相關(guān)子查詢 
一個(gè)列的標(biāo)簽同時(shí)在主查詢和where子句中的查詢中出現(xiàn),那么很可能當(dāng)主查詢中的列值改變之后,子查詢必須重新查詢一次。查詢嵌套層次越多,效率越低,因此應(yīng)當(dāng)盡量避免子查詢。如果子查詢不可避免,那么要在子查詢中過濾掉盡可能多的行。 

5.避免困難的正規(guī)表達(dá)式 
MATCHES和LIKE關(guān)鍵字支持通配符匹配,技術(shù)上叫正規(guī)表達(dá)式。但這種匹配特別耗費(fèi)時(shí)間。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _” 
即使在zipcode字段上建立了索引,在這種情況下也還是采用順序掃描的方式。如果把語句改為SELECT * FROM customer WHERE zipcode >“98000”,在執(zhí)行查詢時(shí)就會(huì)利用索引來查詢,顯然會(huì)大大提高速度。 
另外,還要避免非開始的子串。例如語句:SELECT * FROM customer WHERE zipcode[2,3] >“80”,在where子句中采用了非開始子串,因而這個(gè)語句也不會(huì)使用索引。
6.使用臨時(shí)表加速查詢 
把表的一個(gè)子集進(jìn)行排序并創(chuàng)建臨時(shí)表,有時(shí)能加速查詢。它有助于避免多重排序操作,而且在其他方面還能簡(jiǎn)化優(yōu)化器的工作。例如: 
SELECT cust.name,rcvbles.balance,……other columns 
FROM cust,rcvbles 
WHERE cust.customer_id = rcvlbes.customer_id 
AND rcvblls.balance>0 
AND cust.postcode>“98000” 
ORDER BY cust.name 
如果這個(gè)查詢要被執(zhí)行多次而不止一次,可以把所有未付款的客戶找出來放在一個(gè)臨時(shí)文件中,并按客戶的名字進(jìn)行排序: 
SELECT cust.name,rcvbles.balance,……other columns 
FROM cust,rcvbles 
WHERE cust.customer_id = rcvlbes.customer_id 
AND rcvblls.balance>0 
ORDER BY cust.name 
INTO TEMP cust_with_balance 
然后以下面的方式在臨時(shí)表中查詢: 
SELECT * FROM cust_with_balance 
WHERE postcode>“98000” 
臨時(shí)表中的行要比主表中的行少,而且物理順序就是所要求的順序,減少了磁盤I/O,所以查詢工作量可以得到大幅減少。 
注意:臨時(shí)表創(chuàng)建后不會(huì)反映主表的修改。在主表中數(shù)據(jù)頻繁修改的情況下,注意不要丟失數(shù)據(jù)。 

7.用排序來取代非順序存取 
非順序磁盤存取是最慢的操作,表現(xiàn)在磁盤存取臂的來回移動(dòng)。SQL語句隱藏了這一情況,使得我們?cè)趯憫?yīng)用程序時(shí)很容易寫出要求存取大量非順序頁的查詢。 
有些時(shí)候,用數(shù)據(jù)庫(kù)的排序能力來替代非順序的存取能改進(jìn)查詢。 
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
大數(shù)據(jù)量高并發(fā)的數(shù)據(jù)庫(kù)優(yōu)化
分享一些數(shù)據(jù)庫(kù)使用的心得
如何寫優(yōu)雅的SQL原生語句?
輕松提高千萬級(jí)數(shù)據(jù)庫(kù)查詢效率
MySQL的索引詳解
新手MySQL工程師必備命令速查手冊(cè)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服