當前位置:首頁 » 編程語言 » sql最高效編寫規范
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql最高效編寫規范

發布時間: 2022-04-22 21:04:04

A. 高效地進行sql語句設計遵循哪些方面

1、盡量少用IN操作符,基本上所有的IN操作符都可以用EXISTS代替。不用NOT IN操作符,可以用NOT EXISTS或者外連接+替代。
2、不用「<>」或者「!=」操作符。對不等於操作符的處理會造成全表掃描,可以用「<」 or 「>」代替。
3、Where子句中出現IS NULL或者IS NOT NULL時,Oracle會停止使用索引而執行全表掃描。可以考慮在設計表時,對索引列設置為NOT NULL。這樣就可以用其他操作來取代判斷NULL的操作。
4、當通配符「%」或者「_」作為查詢字元串的第一個字元時,索引不會被使用。
5、對於有連接的列「||」,最後一個連接列索引會無效。盡量避免連接,可以分開連接或者使用不作用在列上的函數替代。
6、如果索引不是基於函數的,那麼當在Where子句中對索引列使用函數時,索引不再起作用。Where子句中避免在索引列上使用計算,否則將導致索引失效而進行全表掃描。
7、對數據類型不同的列進行比較時,會使索引失效。
8、用「>=」替代「>」。
9、UNION操作符會對結果進行篩選,消除重復,數據量大的情況下可能會引起磁碟排序。如果不需要刪除重復記錄,應該使用UNION ALL。
10、Oracle從下到上處理Where子句中多個查詢條件,所以表連接語句應寫在其他Where條件前,可以過濾掉最大數量記錄的條件必須寫在Where子句的末尾。
11、Oracle從右到左處理From子句中的表名,所以在From子句中包含多個表的情況下,將記錄最少的表放在最後。(只在採用RBO優化時有效)
12、Order By語句中的非索引列會降低性能,可以通過添加索引的方式處理。嚴格控制在Order By語句中使用表達式。
13、不同區域出現的相同的Sql語句,要保證查詢字元完全相同,以利用SGA共享池,防止相同的Sql語句被多次分析。
14、多利用內部函數提高Sql效率。例如DECODE
15、當在Sql語句中連接多個表時,使用表的別名,並將之作為每列的前綴。這樣可以減少解析時間。
需要注意的是,隨著Oracle的升級,查詢優化器會自動對Sql語句進行優化,某些限制可能在新版本的Oracle下不再是問題。尤其是採用CBO(Cost-Based Optimization,基於代價的優化方式)時。

B. 如何書寫高效的SQL語句

優化SQL查詢:如何寫出高性能SQL語句
1、首先要搞明白什麼叫執行計劃?
執行計劃是資料庫根據SQL語句和相關表的統計信息作出的一個查詢方案,這個方案是由查詢優化器自動分析產生欀如一條SQL語句如果用來從一個10萬條記錄的表中查1條記錄,那查詢優化器會選擇「索引查找」方式,如果該表進行了歸檔,當前只剩下5000條記錄了,那查詢優化器就會改變方案,採用 「全表掃描」方式。
可見,執行計劃並不是固定的,它是「個性化的」。產生一個正確的「執行計劃」有兩點很重要:
(1) SQL語句是否清晰地告訴查詢優化器它想干什麼?
(2) 查詢優化器得到的資料庫統計信息是否是最新的、正確的?
2、統一SQL語句的寫法
對於以下兩句SQL語句,程序員認為是相同的,資料庫查詢優化器認為是不同的。
select * from al
select * From al
其實就是大小寫不同,查詢分析器就認為是兩句不同的SQL語句,必須進行兩次解析。生成2個執行計劃。
所以作為程序員,應該保證相同的查詢語句在任何地方都一致,多一個空格都不行!
3、不要把SQL語句寫得太復雜
我經常看到,從資料庫中捕捉到的一條SQL語句列印出來有2張A4紙這么長。一般來說這么復雜的語句通常都是有問題的。我拿著這2頁長的SQL語句去請教原作者,結果他說時間太長,他一時也看不懂了。可想而知,連原作者都有可能看糊塗的SQL語句,資料庫也一樣會看糊塗。
一般,將一個Select語句的結果作為子集,然後從該子集中再進行查詢,這種一層嵌套語句還是比較常見的,但是根據經驗,超過3層嵌套,查詢優化器就很容易給出錯誤的執行計劃。因為它被繞暈了。像這種類似人工智慧的東西,終究比人的分辨力要差些,如果人都看暈了,我可以保證資料庫也會暈的。
另外,執行計劃是可以被重用的,越簡單的SQL語句被重用的可能性越高。而復雜的SQL語句只要有一個字元發生變化就必須重新解析,然後再把這一大堆垃圾塞在內存里。可想而知,資料庫的效率會何等低下。
4、使用「臨時表」暫存中間結果
簡化SQL語句的重要方法就是採用臨時表暫存中間結果,但是,臨時表的好處遠遠不止這些,將臨時結果暫存在臨時表,後面的查詢就在tempdb中了,這可以避免程序中多次掃描主表,也大大減少了程序執行中「共享鎖」阻塞「更新鎖」,減少了阻塞,提高了並發性能。

C. 如何優化SQL語句

一、問題的提出
在應用系統開發初期,由於開發資料庫數據比較少,對於查詢SQL語句,復雜視圖的的編寫等體會不出SQL語句各種寫法的性能優劣,但是如果將應用系統提交實際應用後,隨著資料庫中數據的增加,系統的響應速度就成為目前系統需要解決的最主要的問題之一。系統優化中一個很重要的方面就是SQL語句的優化。對於海量數據,劣質SQL語句和優質SQL語句之間的速度差別可以達到上百倍,可見對於一個系統不是簡單地能實現其功能就可,而是要寫出高質量的SQL語句,提高系統的可用性。
在多數情況下,Oracle使用索引來更快地遍歷表,優化器主要根據定義的索引來提高性能。但是,如果在SQL語句的where子句中寫的SQL代碼不合理,就會造成優化器刪去索引而使用全表掃描,一般就這種SQL語句就是所謂的劣質SQL語句。在編寫SQL語句時我們應清楚優化器根據何種原則來刪除索引,這有助於寫出高性能的SQL語句。
二、SQL語句編寫注意問題
下面就某些SQL語句的where子句編寫中需要注意的問題作詳細介紹。在這些where子句中,即使某些列存在索引,但是由於編寫了劣質的SQL,系統在運行該SQL語句時也不能使用該索引,而同樣使用全表掃描,這就造成了響應速度的極大降低。
1.
IS
NULL

IS
NOT
NULL
不能用null作索引,任何包含null值的列都將不會被包含在索引中。即使索引有多列這樣的情況下,只要這些列中有一列含有null,該列就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高性能。
任何在where子句中使用is
null或is
not
null的語句優化器是不允許使用索引的。
2.
聯接列
對於有聯接的列,即使最後的聯接值為一個靜態值,優化器是不會使用索引的。我們一起來看一個例子,假定有一個職工表(employee),對於一個職工的姓和名分成兩列存放(FIRST_NAME和LAST_NAME),現在要查詢一個叫比爾.柯林頓(Bill
Cliton)的職工。
下面是一個採用聯接查詢的SQL語句,
select
*
from
employss
where
first_name||''||last_name
='Beill
Cliton';
上面這條語句完全可以查詢出是否有Bill
Cliton這個員工,但是這里需要注意,系統優化器對基於last_name創建的索引沒有使用。
當採用下面這種SQL語句的編寫,Oracle系統就可以採用基於last_name創建的索引。
***
where
first_name
='Beill'
and
last_name
='Cliton';
.
帶通配符(%)的like語句
同樣以上面的例子來看這種情況。目前的需求是這樣的,要求在職工表中查詢名字中包含cliton的人。可以採用如下的查詢SQL語句:
select
*
from
employee
where
last_name
like
'%cliton%';
這里由於通配符(%)在搜尋詞首出現,所以Oracle系統不使用last_name的索引。在很多情況下可能無法避免這種情況,但是一定要心中有底,通配符如此使用會降低查詢速度。然而當通配符出現在字元串其他位置時,優化器就能利用索引。在下面的查詢中索引得到了使用:
select
*
from
employee
where
last_name
like
'c%';
4.
Order
by語句
ORDER
BY語句決定了Oracle如何將返回的查詢結果排序。Order
by語句對要排序的列沒有什麼特別的限制,也可以將函數加入列中(象聯接或者附加等)。任何在Order
by語句的非索引項或者有計算表達式都將降低查詢速度。
仔細檢查order
by語句以找出非索引項或者表達式,它們會降低性能。解決這個問題的辦法就是重寫order
by語句以使用索引,也可以為所使用的列建立另外一個索引,同時應絕對避免在order
by子句中使用表達式。
5.
NOT
我們在查詢時經常在where子句使用一些邏輯表達式,如大於、小於、等於以及不等於等等,也可以使用and(與)、or(或)以及not(非)。NOT可用來對任何邏輯運算符號取反。下面是一個NOT子句的例子:
...
where
not
(status
='VALID')
如果要使用NOT,則應在取反的短語前面加上括弧,並在短語前面加上NOT運算符。NOT運算符包含在另外一個邏輯運算符中,這就是不等於(<>)運算符。換句話說,即使不在查詢where子句中顯式地加入NOT詞,NOT仍在運算符中,見下例:
...
where
status
<>'INVALID';
對這個查詢,可以改寫為不使用NOT:
select
*
from
employee
where
salary<3000
or
salary>3000;
雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許Oracle對salary列使用索引,而第一種查詢則不能使用索引。
雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許Oracle對salary列使用索引,而第一種查詢則不能使用索引。

D. 如何編寫一個高效的sql語句

少用一些敏感的函數,少連接表,連接表的時候使用exists代替in,not exists代替not in。sql要大寫。在條件中能夠處理掉較多數據的放最後面。等等。

E. 如何提高sql語句的執行效率

1、使用ordered提示

Oracle必須花費大量的時間來剖析多表的合並,用以確定表合並的最佳順序。SQL表達式涉及七個乃至更多的表合並,那麼有時就會需要超過30分鍾的時間來剖析,Ordered這個提示(hint)和其他的提示一起使用能夠產生合適的合並順序。

2、使用ordered_predicates

ordered_predicates提示在查詢的WHERE子句里指定的,並被用來指定布爾判斷(Booleanpredicate)被評估的順序。在沒有ordered_predicates的情況下,Oracle會使用下面這些步驟來評估SQL判斷的順序:子查詢的評估先於外層WHERE子句里的Boolean條件。

所有沒有內置函數或者子查詢的布爾條件都按照其在WHERE子句里相反的順序進行評估,即最後一條判斷最先被評估。每個判斷都帶有內置函數的布爾判斷都依據其預計的評估值按遞增排列。

3、限製表格合並評估的數量

提高SQL剖析性能的最後一種方法是強製取代Oracle的一個參數,這個參數控制著在評估一個查詢的時候,基於消耗的優化器所評估的可能合並數量。

(5)sql最高效編寫規范擴展閱讀:

1、表設計的優化,數據行的長度不要超過8020位元組,如果超過這個長度的話在物理頁中這條數據會佔用兩行從而造成存儲碎片,降低查詢效率。

2、語句的查詢優化,保證在實現功能的基礎上,盡量減少對資料庫的訪問次數;

3、建立高效的索引創建索引一般有以下兩個目的:維護被索引列的唯一性和提供快速訪問表中數據的策略。

大型資料庫有兩種索引即簇索引和非簇索引,一個沒有簇索引的表是按堆結構存儲數據,所有的數據均添加在表的尾部,而建立了簇索引的表,其數據在物理上會按照簇索引鍵的順序存儲。個表只允許有一個簇索引。

4、強制查詢轉換,有時候oracle 的優化器未必能走正確的查詢路線,這個時候就需要添加一些hint 之類的來規定他的執行路線。當然了,這個未必是最好的處理方案。因為雖然現在走這個路線是對的,以為因為數據的變化到這這個HINT 變得不可取。

F. 如何寫出高性能sql語句

盡量不要在where中包含子查詢;
關於時間的查詢,盡量不要寫成:where to_char(dif_date,'yyyy-mm-dd')=to_char('2007-07-01','yyyy-mm-dd');
2
在過濾條件中,可以過濾掉最大數量記錄的條件必須放在where子句的末尾;
FROM子句中寫在最後的表(基礎表,driving table)將被最先處理,在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表。如果有三個以上的連接查詢,那就需要選擇交叉表(intersection table)作為基礎表,交叉表是指那個被其他表所引用的表;
3
採用綁定變數
4
在WHERE中盡量不要使用OR
5
用EXISTS替代IN、用NOT EXISTS替代NOT IN;
6
避免在索引列上使用計算:WHERE SAL*12>25000;
7
用IN來替代OR: WHERE LOC_ID=10 OR LOC_ID=15 OR LOC_ID=20
8
避免在索引列上使用IS NULL和IS NOT NULL;
9
總是使用索引的第一個列;
10
用UNION-ALL替代UNION;
11
避免改變索引列的類型:SELECT...FROM EMP WHERE EMPNO='123',由於隱式數據類型轉換,to_char(EMPNO)='123',因此,將不採用索引,一般在採用字元串拼湊動態SQL語句出現;
12
'!=' 將不使用索引;
13
優化GROUP BY;
14
避免帶有LIKE參數的通配符,LIKE '4YE%'使用索引,但LIKE '%YE'不使用索引
15
避免使用困難的正規表達式,例如select * from customer where zipcode like "98___",即便在zipcode上建立了索引,在這種情況下也還是採用順序掃描的方式。如果把語句改成select * from customer where zipcode>"98000",在執行查詢時就會利用索引來查詢,顯然會大大提高速度;
16
盡量明確的完成SQL語句,盡量少讓資料庫工作。比如寫SELECT語句時,需要把查詢的欄位明確指出表名。盡量不要使用SELECT *語句。組織SQL語句的時候,盡量按照資料庫的習慣進行組織。

G. 怎麼樣寫SQL語句可以提高資料庫的執行速度應該注意那些

這個范圍太大了,一下子是很難說清楚的,如果用sql server 的話,可以使用它自帶的優化器來優化,然後看看它給你的建議去優化。要注意規范化編程。而且要抓住一個原則來寫,就是進可能縮小查詢出來的結果集,哪怕多次查詢都沒所謂,要一步一步把大數據量縮小。很多隻是還是得在時間中優化。SET STATISTICS TIME ON;SQL 語句SET STATISTICS TIME OFF;這個是sqlserver ,可以測出執行時間。編寫的時候要時刻想著:縮小結果集、減少連接次數和表數。大數據量不要用update,可以用臨時表作為過度來實現update操作。

H. 如何進行SQL性能優化

這里分享下mysql優化的幾種方法。

1、首先在打開的軟體中,需要分別為每一個表創建 InnoDB FILE的文件。