日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

sql優(yōu)化原則與技巧

 xctdlxg 2016-03-14

加快sql查詢是非常重要的技巧,簡(jiǎn)單來(lái)說(shuō)加快sql查詢的方式有以下幾種:一、索引的引用

1、索引一般可以加速數(shù)據(jù)的檢索速度,加速表與表之間的鏈接,提高性能,所以在對(duì)海量數(shù)據(jù)進(jìn)行處理時(shí),考慮到信息量比較大,應(yīng)該對(duì)表建立索引,包括在主鍵上建立聚簇索引,將聚合索引建立在日期刊上等。索引的優(yōu)點(diǎn)有很多,但是對(duì)于索引的建立,還需要考慮實(shí)際情況,而不是對(duì)每一個(gè)列建立一個(gè)索引,比如針對(duì)大表的分組、排序等字段,都要建立相應(yīng)索引,同時(shí)還應(yīng)該考慮建立符合索引。增加索引的同時(shí)也有很多不好的方面,首先,創(chuàng)建索引和維護(hù)索引都耗費(fèi)時(shí)間,且隨著數(shù)據(jù)量的增加而增加;其次,索引占據(jù)物理空間,聚簇索引的空間更大。最后,當(dāng)對(duì)表進(jìn)行增加、刪除和修改的時(shí)候,索引也要?jiǎng)討B(tài)的維護(hù)。所以索引的引用有以下幾個(gè)原則:

(1)當(dāng)插入數(shù)據(jù)為表中數(shù)據(jù)的百分之10以上時(shí),首先需要?jiǎng)h除該表的索引來(lái)提高數(shù)據(jù)的插入效率,然后再重新建立索引;

(2)避免在索引列上使用函數(shù)或計(jì)算,在where字句中,如果索引是函數(shù)的一部分,優(yōu)化器將不再使用索引,將使用全表掃描;例如:

select * from table where hh*10>1000;//低效
select * from table where hh>1000/10;//更高效

(3)盡量避免在索引列上使用not,!=和<>,索引只能告訴什么在表中,而不能告訴什么不在表中,當(dāng)數(shù)據(jù)庫(kù)遇上以上幾種符號(hào)時(shí),將不再使用索引,使用全表掃描

(4)檢索中不要對(duì)索引進(jìn)行處理,如TRIM,TO_DATE,類型轉(zhuǎn)換等,這會(huì)破壞索引

(5)避免在索引列上使用IS NULL 或 IS NOT NULL。避免在索引列上使用任何可以為空的列,這樣將無(wú)法使用此索引。因?yàn)榭罩挡淮嬖谟谒饕兄?,所以?dāng)where字句中對(duì)索引進(jìn)行空值比較,將無(wú)法使用該索引。

(6)在索引列上,使用>=代替>,比如:

select * from table where hh>10;//低效
select * from table where hh>=10.0000001//相對(duì)高效

二、SQL語(yǔ)句的優(yōu)化

介紹幾種SQL語(yǔ)句的優(yōu)化技巧:

(1)where字句中的鏈接順序

oracle采用自下而上的順序解析where字句,所以表之間的鏈接必須寫(xiě)在其他where條件之前,那些可以濾過(guò)大量紀(jì)錄的條件必須寫(xiě)在where字句的末尾,例如:

select * from table e
      where h>500     
 and d='001'
 and 25<(select count(*) 
 from table 
 where count=e.count);  //低效

select * from table e
      where  25<(select count(*) 
 from table 
 where count=e.count);    
 and  h>500
 and d='001';//更高效     

(2)刪除全表時(shí),用truncate而不用delete。因?yàn)閠runcate是ddl不是dml(truncate只能在刪除全表時(shí)使用),例如:

Truncate table account;
比
delete from account;
快1000倍

(3)盡量多使用commit,只要有可能就對(duì)程序中每個(gè)delete,insert,update使用commit,這樣系統(tǒng)會(huì)因?yàn)閏ommit所釋放的資源而大大提高效率。

(4)用exists代替in,可以提高查詢的效率。例如:

SELECT * FROM ACCOUNT
    WHERE AC_CODE 
    NOT IN (
 SELECT CODE
 FROM GOODS
 WHERE NUM='001')       //低效

SELECT * FROM ACCOUNT
    WHERE NOT EXISTS
       (SELECT CODE
 FROM GOODS
 WHERE CODE=ACCOUNT.AC_CODE
 AND NUM='001') //更高效

(5)使用group by

可以將不需要的語(yǔ)句在group by之前過(guò)濾掉

sql優(yōu)化原則與技巧

(6)避免使用HAVING字句

HAVING字句只有在檢索出所有記錄之后,才會(huì)對(duì)結(jié)果集進(jìn)行過(guò)濾,這樣涉及到排序,統(tǒng)計(jì)等操作,如果能通過(guò)WHERE字句限制記錄的數(shù)目,就可以減少開(kāi)銷。用Where子句替換HAVING子句,如果能通過(guò)WHERE子句限制記錄的數(shù)目,那就能減少這方面的開(kāi)銷. (非oracle中)on、where、having這三個(gè)都可以加條件的子句中,on是最先執(zhí)行,where次之,having最后,因?yàn)閛n是先把不 符合條件的記錄過(guò)濾后才進(jìn)行統(tǒng)計(jì),它就可以減少中間運(yùn)算要處理的數(shù)據(jù),按理說(shuō)應(yīng)該速度是最快的,where也應(yīng)該比having快點(diǎn)的,因?yàn)樗^(guò)濾數(shù)據(jù)后 才進(jìn)行sum,在兩個(gè)表聯(lián)接時(shí)才用on的,所以在一個(gè)表的時(shí)候,就剩下where跟having比較了。在這單表查詢統(tǒng)計(jì)的情況下,如果要過(guò)濾的條件沒(méi)有涉及到要計(jì)算字段,那它們的結(jié)果是一樣的,只是where可以使用rushmore技術(shù),而having就不能,在速度上后者要慢如果要涉及到計(jì)算的字 段,就表示在沒(méi)計(jì)算之前,這個(gè)字段的值是不確定的,根據(jù)上篇寫(xiě)的工作流程,where的作用時(shí)間是在計(jì)算之前就完成的,而having就是在計(jì)算后才起作 用的,所以在這種情況下,兩者的結(jié)果會(huì)不同。在多表聯(lián)接查詢時(shí),on比where更早起作用。系統(tǒng)首先根據(jù)各個(gè)表之間的聯(lián)接條件,把多個(gè)表合成一個(gè)臨時(shí)表 后,再由where進(jìn)行過(guò)濾,然后再計(jì)算,計(jì)算完后再由having進(jìn)行過(guò)濾。由此可見(jiàn),要想過(guò)濾條件起到正確的作用,首先要明白這個(gè)條件應(yīng)該在什么時(shí)候起作用,然后再?zèng)Q定放在那里 。

(7)有條件的使用union-all代替union提高效率

(8)在所有查詢的SQL語(yǔ)句中要特別注意減少對(duì)表的查詢,如:

sql優(yōu)化原則與技巧

(9)select字句中避免使用*

當(dāng)想在select字句中列出所有的列時(shí),使用*是一個(gè)很方便,但是很低效的方法,因?yàn)樵趏racle中,會(huì)通過(guò)查詢數(shù)據(jù)字典,將*依次轉(zhuǎn)換為所有的列名,很耗時(shí)

(10)Order by語(yǔ)句

ORDER BY語(yǔ)句決定了Oracle如何將返回的查詢結(jié)果排序。Order by語(yǔ)句對(duì)要排序的列沒(méi)有什么特別的限制,也可以將函數(shù)加入列中(象聯(lián)接或者附加等)。任何在Order by語(yǔ)句的非索引項(xiàng)或者有計(jì)算表達(dá)式都將降低查詢速度。仔細(xì)檢查order by語(yǔ)句以找出非索引項(xiàng)或者表達(dá)式,它們會(huì)降低性能。解決這個(gè)問(wèn)題的辦法就是重寫(xiě)order by語(yǔ)句以使用索引,也可以為所使用的列建立另外一個(gè)索引,同時(shí)應(yīng)絕對(duì)避免在order by子句中使用表達(dá)式。

(11)帶通配符(%)的like語(yǔ)句

目前的需求是這樣的,要求在職工表中查詢名字中包含cliton的人??梢圆捎萌缦碌牟樵僑QL語(yǔ)句:

select*fromemployeewherelast_namelike'%cliton%';

這里由于通配符(%)在搜尋詞首出現(xiàn),所以O(shè)racle系統(tǒng)不使用last_name的索引。在很多情況下可能無(wú)法避免這種情況,但是一定要心中有底,通配符如此使用會(huì)降低查詢速度。然而當(dāng)通配符出現(xiàn)在字符串其他位置時(shí),優(yōu)化器就能利用索引。在下面的查詢中索引得到了使用:

select*fromemployeewherelast_namelike'c%';

(12)選擇最有效率的表名順序(只在基于規(guī)則的優(yōu)化器中有效):

ORACLE的解析器按照從右到左的順序處理FROM子句中的表名,F(xiàn)ROM子句中寫(xiě)在最后的表(基礎(chǔ)表driving table)將被最先處理,在FROM子句中包含多個(gè)表的情況下,你必須選擇記錄條數(shù)最少的表作為基礎(chǔ)表。如果有3個(gè)以上的表連接查詢,那就需要選擇交叉表(intersection table)作為基礎(chǔ)表,交叉表是指那個(gè)被其他表所引用的表。

(13)整合簡(jiǎn)單,無(wú)關(guān)聯(lián)的數(shù)據(jù)庫(kù)訪問(wèn):如果你有幾個(gè)簡(jiǎn)單的數(shù)據(jù)庫(kù)查詢語(yǔ)句,你可以把它們整合到一個(gè)查詢中(即使它們之間沒(méi)有關(guān)系)

(14)刪除重復(fù)記錄:

最高效的刪除重復(fù)記錄方法(因?yàn)槭褂昧薘OWID)例子:

DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)

FROM EMP X WHERE X.EMP_NO = E.EMP_NO);

(15)使用表的別名(Alias):

當(dāng)在SQL語(yǔ)句中連接多個(gè)表時(shí),請(qǐng)使用表的別名并把別名前綴于每個(gè)Column上.這樣一來(lái),就可以減少解析的時(shí)間并減少那些由Column歧義引起的語(yǔ)法錯(cuò)誤。

(16)sql語(yǔ)句用大寫(xiě)的;因?yàn)閛racle總是先解析sql語(yǔ)句,把小寫(xiě)的字母轉(zhuǎn)換成大寫(xiě)的再執(zhí)行(17) 在java代碼中盡量少用連接符“+”連接字符串!

(18)總是使用索引的第一個(gè)列:如果索引是建立在多個(gè)列上,只有在它的第一個(gè)列(leading column)被where子句引用時(shí),優(yōu)化器才會(huì)選擇使用該索引.這也是一條簡(jiǎn)單而重要的規(guī)則,當(dāng)僅引用索引的第二個(gè)列時(shí),優(yōu)化器使用了全表掃描而忽略了索引

三、函數(shù)的使用技巧

雖然有時(shí)肆意的使用函數(shù),會(huì)將性能降低,但是用好函數(shù)有時(shí)也能提高性能和可讀性。如:

sql優(yōu)化原則與技巧sql優(yōu)化原則與技巧sql優(yōu)化原則與技巧sql優(yōu)化原則與技巧

其他的一些方法可以參考http://www.cnblogs.com/ziyiFly/archive/2008/12/24/1361380.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多