SQL 查詢效率優化原則

點擊上方 java項目開發選擇 設爲星標前端

優質文章,及時送達vue

--

一、對查詢進行優化,應儘量避免全表掃描java

首先應考慮在 where 及 order by 涉及的列上創建索引。
下面咱們來以一個表中177條數據比較一下,全表掃描與創建索引以後性能的一個比較.
react

1.1 全表查詢web

1.2 創建索引查詢

1.3 結論

從這兩種方式查詢數據庫結果看,創建索引以後查詢速度提升了些,如今數據量還不明顯,若是表中有10萬條速度,差別就會很明顯了.spring

二、寫數據語句時儘量減小表的全局掃描

2.1 減小where 字段值null判斷數據庫

SELECT * FROM "tb_real_time_car"where pay_status =null
  
  
   
   
            
   
   
如何這樣作,就會致使引擎放棄使用索引而進行全表掃描
應該這樣去設置(也就是在沒有值時,咱們在存數據庫時自動默認給個o值,而不是什麼都不寫):
SELECT * FROM "tb_real_time_car"where pay_status =0
  
  
   
   
            
   
   

2.2 應儘可能避免在 where 子句中使用!=或<>操做符小程序

SELECT * FROM "tb_real_time_car"where pay_status !=null;
//或者
SELECT * FROM "tb_real_time_car"where pay_status <>null;


這樣寫將致使引擎放棄使用索引而進行全表掃描。
2.3 應儘可能避免在 where 子句中使用 or 來鏈接條件
SELECT * FROM "tb_real_time_car"where pay_status !=nullor enter_time =null;
  
  
   
   
            
   
   
這樣將致使引擎放棄使用索引而進行全表掃描
能夠這樣操做:
SELECT * FROM "tb_real_time_car"where pay_status !=nullunion all
SELECT * FROM "tb_real_time_car"where enter_time =null;


2.4 in 和 not in 也要慎用
SELECT * FROM "tb_real_time_car"where rowed in[1,2,3,4]; 
//或者
SELECT * FROM "tb_real_time_car"where rowed notin[1,2,3,4];
這樣操做,也會致使全表掃描
能夠這樣來寫:
SELECT * FROM "tb_real_time_car"where rowed between 1and5;
  
  
   
   
            
   
   
2.5 少使用模糊匹配 like
SELECT * FROM "tb_real_time_car"where enter_time like '%2016-09-01%'
  
  
   
   
            
   
   

2.6 應儘可能避免在 where 子句中對字段進行表達式操做後端

SELECT * FROM "tb_real_time_car"where rowid/4=100;
  
  
   
   
            
   
   

這樣寫,將致使引擎放棄使用索引而進行全表掃描微信小程序

應該寫成:
SELECT * FROM "tb_real_time_car"where rowid =4*100;
  
  
   
   
            
   
   

2.7 任何地方都不要使用*通配符去查詢全部

SELECT * FROM "tb_real_time_car"where rowid/4=100;
  
  
   
   
            
   
   

以通配符*去查詢全部數據,這樣作也是很是耗時的,咱們應該須要什麼字段就查詢什麼字段.

應該這樣作:
SELECT leave_time FROM "tb_real_time_car"where rowid/4=100;
  
  
   
   
            
   
   

三、不要在條件判斷時進行 算數運算

SELECT * FROM "tb_real_time_car"where rowid/4=100;


  
  
   
   
            
   
   
因此不要在 where 子句中的「=」左邊進行函數、算術運算或其餘表達式運算,這樣系統將可能沒法正確使用索引
應該這樣作:
SELECT * FROM "tb_real_time_car"where rowed =400;
  
  
   
   
            
   
   

四、不少時候用 exists 代替 in 是一個好的選擇

SELECT * FROM "tb_real_time_car"where rowed (select rowed from"tb_real");


  
  
   
   
            
   
   
應該這樣來寫:
SELECT * FROM "tb_real_time_car"where exists (select rowed from"tb_real"where rowed = tb_real.rowid);
  
  
   
   
            
   
   

5 論索引技巧

5.1 並非全部索引對查詢都有效
SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重複時,SQL查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那麼即便在sex上建了索引也對查詢效率起不了做用
5.2 索引並非越多越好
索引當然能夠提升相應的 select 的效率,但同時也下降了 insert 及 update 的效率,由於 insert 或 update 時有可能會重建索引,因此怎樣建索引須要慎重考慮,視具體狀況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。
5.3 應儘量的避免更新 clustered 索引數據列
由於 clustered 索引數據列的順序就是表記錄的物理存儲順序,一旦該列值改變將致使整個表記錄的順序的調整,會耗費至關大的資源。若應用系統須要頻繁更新 clustered 索引數據列,那麼須要考慮是否應將該索引建爲 clustered 索引。
5.4 儘可能使用數字型字段
若只含數值信息的字段儘可能不要設計爲字符型,這會下降查詢和鏈接的性能,並會增長存儲開銷。這是由於引擎在處理查詢和鏈接時會逐個比較字符串中每個字符,而對於數字型而言只須要比較一次就夠了。
5 建立數據庫時應該注意地方
5.1. 儘量的使用 varchar/nvarchar 代替 char/nchar
由於首先變長字段存儲空間小,能夠節省存儲空間,其次對於查詢來講,在一個相對較小的字段內搜索效率顯然要高些。
5.2 用表變量來代替臨時表。
  • 若是表變量包含大量數據,請注意索引很是有限(只有主鍵索引)。
  • 在新建臨時表時,若是一次性插入數據量很大,那麼可使用 select into 代替 create table,避免形成大量 log ,以提升速度;若是數據量不大,爲了緩和系統表的資源,應先create table,而後insert。
  • 若是使用到了臨時表,在存儲過程的最後務必將全部的臨時表顯式刪除,先 truncate table ,而後 drop table ,這樣能夠避免系統表的較長時間鎖定。
  • 避免頻繁建立和刪除臨時表,以減小系統表資源的消耗。

4 儘可能避免使用遊標
  • 由於遊標的效率較差,如 果遊標操做的數據超過1萬行,那麼就應該考慮改寫。
  • 使用基於遊標的方法或臨時表方法以前,應先尋找基於集的解決方案來解決問題,基於集的方法一般更有效。
  • 與臨時表同樣,遊標並非不可以使用。對小型數據集使用 FAST_FORWARD 遊標一般要優於其餘逐行處理方法,尤爲是在必須引用幾個表才能得到所需的數據時。在結果集中包括「合計」的例程一般要比使用遊標執行的速度快。若是開發時間容許,基於遊標的方法和基於集的方法均可 以嘗試一下,看哪種方法的效果更好。

6 數據放回時注意什麼

6.1 儘可能避免大事務操做,提升系統併發能力。
這樣能夠有效提升系統的併發能力
6.2 儘可能避免向客戶端返回大數據量
若數據量過大,應該考慮相應需求是否合理。
7.總結
1.儘可能避免where中包含子查詢;
2.where條件中,過濾量最大的條件放在where子句最後;
3.採用綁定變量有助於提升效率;
4.在索引列上使用計算、改變索引列的類型、在索引列上使用!=將放棄索引;
5.運算符效率:exists高於in高於or,(not exists高於not in);
(這裏指出:in和or都是效率較低的運算,可是in的效率:O(logn)仍然比or的效率:O(n)高的多,尤爲當運算列不是索引的時候尤其明顯)
6.避免在索引列上使用is
null和is not null;
7.使用索引的第一個列;
8.用union-all替代union;
9.like ‘text%’使用索引,但like ‘%text’不使用索引;
   


- END -

推薦案例

溫暖提示

爲了方便你們更好的學習,本公衆號常常分享一些完整的單個功能案例代碼給你們去練習, 若是本公衆號沒有你要學習的功能案例,你能夠聯繫小編(微信:xxf960513)提供你的小需求給我,我安排咱們這邊的開發團隊免費幫你完成你的案例。
注意:只能提單個功能的需求不能要求功能太多,好比要求用什麼技術,有幾個頁面,頁面要求怎麼樣?




請長按識別二維碼

想學習更多的java功能案例請關注

Java項目開發


若是你以爲這個案例以及咱們的分享思路不錯,對你有幫助,請分享給身邊更多須要學習的朋友。別忘了《留言+點在看》給做者一個鼓勵哦!

本文分享自微信公衆號 - web項目開發(javawebkaifa)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索