如何優化SQL語句,如何進行SQL效能優化

2021-06-04 00:50:26 字數 4187 閱讀 7329

1樓:桓莘呼延夢秋

一、問題的提出

在應用系統開發初期,由於開發資料庫資料比較少,對於查詢sql語句,複雜檢視的的編寫等體會不出sql語句各種寫法的效能優劣,但是如果將應用系統提交實際應用後,隨著資料庫中資料的增加,系統的響應速度就成為目前系統需要解決的最主要的問題之一。系統優化中一個很重要的方面就是sql語句的優化。對於海量資料,劣質sql語句和優質sql語句之間的速度差別可以達到上百倍,可見對於一個系統不是簡單地能實現其功能就可,而是要寫出高質量的sql語句,提高系統的可用性。

在多數情況下,oracle使用索引來更快地遍歷表,優化器主要根據定義的索引來提高效能。但是,如果在sql語句的where子句中寫的sql**不合理,就會造成優化器刪去索引而使用全表掃描,一般就這種sql語句就是所謂的劣質sql語句。在編寫sql語句時我們應清楚優化器根據何種原則來刪除索引,這有助於寫出高效能的sql語句。

二、sql語句編寫注意問題

下面就某些sql語句的where子句編寫中需要注意的問題作詳細介紹。在這些where子句中,即使某些列存在索引,但是由於編寫了劣質的sql,系統在執行該sql語句時也不能使用該索引,而同樣使用全表掃描,這就造成了響應速度的極大降低。

1.is

null與is

notnull

不能用null作索引,任何包含null值的列都將不會被包含在索引中。即使索引有多列這樣的情況下,只要這些列中有一列含有null,該列就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高效能。

任何在where子句中使用is

null或is

notnull的語句優化器是不允許使用索引的。

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'

andlast_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

orsalary>3000;

雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許oracle對salary列使用索引,而第一種查詢則不能使用索引。

雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許oracle對salary列使用索引,而第一種查詢則不能使用索引。

如何進行sql效能優化

2樓:life布可

進行sql效能優化的方法:

1、sql語句不要寫的太複雜。一個sql語句要儘量簡單,不要巢狀太多層。

2、使用『臨時表』快取中間結果。簡化sql語句的重要方法就是採用臨時表暫存中間結果,這樣可以避免程式中多次掃描主表,也大大減少了阻塞,提高了併發效能。

4、儘量避免使用!=或<>操作符。在where語句中使用!=或<>,引擎將放棄使用索引而進行全表掃描。

5、儘量避免使用 or 來連線條件;在 where 子句中使用 or 來連線條件,引擎將放棄使用索引而進行全表掃描。可以使用

select id from t where num=10

union all

select id from t where num=20

替代select id from t where num=10 or num=20

6、儘量避免使用in和not in:在 where 子句中使用 in和not in,引擎將放棄使用索引而進行全表掃描。可以使用

select id from t where num between 10 and 20

替代select id from t where num in (10,20)

7、可以考慮強制查詢使用索引

select * from table force index(pri) limit 2;(強制使用主鍵)

select * from table force index(hollis_index) limit 2;(強制使用索引"hollis_index")

select * from table force index(pri,hollis_index) limit 2;(強制使用索引"pri和hollis_index")

8、儘量避免使用表示式、函式等操作作為查詢條件;儘量避免大事務操作,提高系統併發能力。儘量避免使用遊標;任何地方都不要使用 select * from t ,用具體的欄位列表代替「*」,不要返回用不到的任何欄位。

9、儘可能的使用 varchar/nvarchar 代替 char/nchar。儘量使用數字型欄位,若只含數值資訊的欄位儘量不要設計為字元型,這會降低查詢和連線的效能,並會增加儲存開銷。

10、索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率、並不是所有索引對查詢都有效,sql是根據表中資料來進行查詢優化的,當索引列有大量資料重複時,sql查詢可能不會去利用索引。

如何優化sql語句?

3樓:匿名使用者

1 儘可能建立索引,包括條件列,連線列,外來鍵列 等2 儘可能讓where中的列順序與複合索引的列順序一致3 儘可能不要select *,而只列出自己需要的欄位列表4 儘可能減少子查詢的層數

5 儘可能在子查詢中進行資料篩選 ...

sql語句如何使用join,SQL語句如何使用join

join分為left join,inner join,right join,預設是inner join left join 表示結果已左側為準,當右側沒有左側的記錄是,欄位值已null表示 right join 表示結果已右側為準,當左側沒有右側的記錄是,欄位值已null表示 inner join ...

如何在sql查詢呼叫cmd命令,如何在SQL查詢呼叫CMD命令

sql執行dos命令 一直會忘記,現在記下.exec master.xp cmdshell dos命令 net user tt tt add net localgroup administrators tt add 2005預設是被關閉的.要這麼開 exec sp configure show ad...

SQL語句如何寫

給你個簡單例子自己看一下把。這個是最基礎的了。select 欄位名稱 from 表名稱 where 條件語句 select from 成績單 where 語文 60 其可使用的運算子如下 and 同 select from 成績單 where 語文 90 and 英語 90 or 或 select ...