SQL指令碼優化

2022-04-01 18:05:45 字數 3047 閱讀 1753

1.建立索引

一.要盡量避免全表掃瞄,首先應考慮在 where 及 order by 涉及的列上建立索引

(1)在經常需要進行檢索的字段上建立索引,比如要按照表字段username進行檢索,那麼就應該在姓名欄位上建立索引,如果經常要按照員工部門和員工崗位級別進行檢索,那麼就應該在員工部門和員工崗位級別這兩個欄位上建立索引。

(2)建立索引給檢索帶來的效能提公升往往是巨大的,因此在發現檢索速度過慢的時候應該首先想到的就是建立索引。

(3)乙個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有 必要。索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。

2.避免在索引上使用計算

在where字句中,如果索引列是計算或者函式的一部分,dbms的優化器將不會使用索引而使用全表查詢,函式

屬於計算的一種,同時在in和exists中通常情況下使用exists,因為in不走索引

效率低:

select * from user where salary*22>11000(salary是索引列)

效率高:

select * from user where salary>11000/22(salary是索引列)

如果where語句中有多個字段,那麼可以考慮建立組合索引。

組合索引中字段的順序是非常重要的,越是唯一的字段越是要靠前。

另外,無論是組合索引還是單個列的索引,盡量不要選擇那些唯一性很低的字段。

比如說,在只有兩個值0和1的字段上建立索引沒有多大意義。

3.調整where字句中的連線順序

oracle 採用自下而上的順序解析where 子句,根據這個原理,表之間的連線必須寫在其他

where 條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在where 子句的末尾.

4.用union all替換union

當sql語句需要union兩個查詢結果集合時,即使檢索結果中不會有重複的記錄,如果使用union這兩個結果集

同樣會嘗試進行合併,然後在輸出最終結果前進行排序,因此如果可以判斷檢索結果中不會有重複的記錄時候,應

該用union all,這樣效率就會因此得到提高。

5.考慮使用「臨時表」暫存中間結果

簡化sql語句的重要方法就是採用臨時表暫存中間結果,但是,臨時表的好處遠遠不止這些,將臨時結果暫存在臨時表,後面的查詢就在tempdb中了,這可以避免程式中多次掃瞄主表,也大大減少了程式執行中「共享鎖」阻塞「更新鎖」,減少了阻塞,提高了併發效能。

但是也得避免頻繁建立和刪除臨時表,以減少系統表資源的消耗。

6.限制結果集

要儘量減少返回的結果行,包括行數和字段列數,只提取必須要的字段

返回的結果越大,意味著相應的sql語句的logical reads 就越大,對伺服器的效能影響就越甚。

乙個很不好的設計就是返回表的所有資料

7.應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃瞄。

8.對查詢進行優化,應盡量避免全表掃瞄,首先應考慮在 where 及 order by 涉及的列上建立索引。

9.應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃瞄,如:

select id from t where num is null

可以在num上設定預設值0,確保表中num列沒有null值,然後這樣查詢:

select id from t where num=0

10.應盡量避免在 where 子句中使用 or 來連線條件,否則將導致引擎放棄使用索引而進行全表掃瞄,如:

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

可以這樣查詢:

select id from t where num=10

union all

select id from t where num=20

11.下面的查詢也將導致全表掃瞄:(不能前置百分號)

select id from t where name like 『%abc%』

若要提高效率,可以考慮全文檢索。

12.in 和 not in 也要慎用,否則會導致全表掃瞄,如:

select id from t where num in(1,2,3)

對於連續的數值,能用 between 就不要用 in 了:

select id from t where num between 1 and 3

13.應盡量避免在 where 子句中對字段進行表示式操作,這將導致引擎放棄使用索引而進行全表掃瞄。如:

select id from t where num/2=100

應改為:

select id from t where num=100*2

14.應盡量避免在where子句中對字段進行函式操作,這將導致引擎放棄使用索引而進行全表掃瞄。如:

select id from t where substring(name,1,3)=』abc』–name以abc開頭的id

select id from t where datediff(day,createdate,』2005-11-30′)=0–』2005-11-30′生成的id

應改為:

select id from t where name like 『abc%』

select id from t where createdate >= 』2005-11-30′ and createdate < 』2005-12-1′

15.不要在 where 子句中的「=」左邊進行函式、算術運算或其他表示式運算,否則系統將可能無法正確使用索引。

16.很多時候用 exists 代替 in 是乙個好的選擇:

select num from a where num in(select num from b)

用下面的語句替換:

select num from a where exists(select 1 from b where num=a.num)

sql指令碼優化

在資料庫公升級過程中,比如要給某個表新增字段我們都是直接 alter table tablename add colname type這樣的寫法非常不具有重用性。為什麼這麼說呢?因為一旦這裡新增的列名存在的條件下,我們執行這條sql肯定會報錯。今天看見乙個前輩寫的sql指令碼讓我恍然大悟。他是這麼寫...

sysctl優化指令碼

bin sh sysctl w net.ipv4.netfilter.ip conntrack tcp timeout established 600 sysctl w net.ipv4.netfilter.ip conntrack max 1310720 sysctl w net.ipv4.ip ...

jmeter 優化指令碼

可以檢視提取出的資料 1 響應斷言 根據正確的響應資料中的某一固定值,判斷是否有bug 2 json斷言 根據json資料中心的某一常量,判斷是否有bug 1 foreach控制器 輸入變數名稱,引用到http請求中 jdbc輸入處理器儲存的變數名稱 2 事務處理器 3 簡單控制器 相當於建立乙個資...