count查詢優化

  這裏討論的count查詢優化是針對INNODB存儲引擎的!java

  首先拋出一個問題sql

  count(*)、count(主鍵)、count(1)、count(字段)它們四者之間的效率如何排序?函數

  在咱們以往的工做經驗中,老是聽到說不要使用count(*),由於 * 號表明了全部列,計算會更慢,而後就推薦了使用count(主鍵)。但事實真的是這樣嗎?性能

筆者在最近的學習中也才認識到這個錯誤。學習

  這四者正確的排序應該是這樣的:測試

count(1) > count(*) > count(主鍵) > count(字段)

  筆者特地在一張只有主鍵索引的1千萬條數據的表中作了測試,如下是測試的結果:優化

       

 

   這張圖的數據不是偶然的,筆者針對每種查詢執行了屢次,結果不會有太大的變化,驗證了以上排序的正確性。code

  count()的做用blog

  count()是一個特殊的函數,有兩種很是不一樣的做用:它能夠統計某個列值的數量,也能夠統計行數。在統計列值時要求列值排序

是非空的(不統計NULL)。若是在count()的括號中指定了列或者列的表達式,則統計的就是這個表達式有值的結果數,而不是NULL。

  count()的另外一個做用是統計結果集的行數。當MYSQL確認括號內的表達式值不可能爲空時,實際上就是在統計行數。最簡單的就

是當咱們使用count(*)的時候,這種狀況下通配符 * 並不會像咱們猜測的那樣擴展成全部的列,實際上,它會忽略全部的列而直接統計

全部的行數。

  最多見的一個錯誤就是,在括號內指定了一個列卻但願統計結果集的行數。若是但願知道的是結果集的行數,最好使用COUNT(*),

這樣寫意義清晰,性能也會很好。

  count()的另外一個優化

  業務代碼中,有這樣一個需求,須要根據一個或多個條件,查詢是否存在記錄,不關心有多少條記錄。廣泛的SQL及代碼寫法以下:

SELECT count(*) FROM T WHERE a = 1 AND b = 2

  java寫法以下

Integer exist = xxDao.existXxxxByXxx(params);
if ( exist != NULL ) {
  //當存在時,執行這裏的代碼
} else {
  //當不存在時,執行這裏的代碼
}

  對於此處的select count(*),並不需求將符合條件的條數都統計出來,能夠優化成以下的SQL:

SELECT count(*) FROM T WHERE a = 1 AND b = 2 LIMIT 1

  這裏相比上面的SQL多了LIMIT關鍵字,在MYSQL中,執行器執行到LIMIT關鍵字,只要知足LIMIT的條數,存儲引擎就不會再對數據文件

進行檢索,直接返回,因此這裏只須要檢索到1條以後就返回結果,效率可想而知快了很多!

相關文章
相關標籤/搜索