SQL查找是否"存在",別再用count了
根據某一條件從數據庫表中查詢『有』與『沒有』,只有兩種狀態,那為什么在寫 SQL 的時候,還要 SELECT COUNT(*) 呢?
圖片來自 Pexels
無論是剛入道的程序員新星,還是精湛沙場多年的程序員老白,都是一如既往的 COUNT。
目前多數人的寫法
多次 REVIEW 代碼時,發現如現現象:業務代碼中,需要根據一個或多個條件,查詢是否存在記錄,不關心有多少條記錄。
普遍的 SQL 及代碼寫法如下:
- ##### SQL寫法:
- SELECT count(*) FROM table WHERE a = 1 AND b = 2
- ##### Java寫法:
- int nums = xxDao.countXxxxByXxx(params);
- if ( nums > 0 ) {
- //當存在時,執行這里的代碼
- } else {
- //當不存在時,執行這里的代碼
- }
是不是感覺很 OK,沒有什么問題?
優化方案
推薦寫法如下:
- ##### SQL寫法:
- SELECT 1 FROM table WHERE a = 1 AND b = 2 LIMIT 1
- ##### Java寫法:
- Integer exist = xxDao.existXxxxByXxx(params);
- if ( exist != NULL ) {
- //當存在時,執行這里的代碼
- } else {
- //當不存在時,執行這里的代碼
- }
SQL 不再使用 COUNT,而是改用 LIMIT 1,讓數據庫查詢時遇到一條就返回,不要再繼續查找還有多少條了。
業務代碼中直接判斷是否非空即可!
根據查詢條件查出來的條數越多,性能提升的越明顯,在某些情況下,還可以減少聯合索引的創建。
總結
COUNT() 有兩個非常不同的作用:
它可以統計某個列值的數量,也可以統計行數。在統計列值時要求列值是非空的(不統計 NULL)。
如果在 COUNT() 的括號中定了列或者列表達式,則統計的就是這個表達式有值的結果數。......COUNT() 的另一個作用是統計結果集的行數。當 MySQL 確認括號內的表達式值不可能為空時,實際上就是在統計行數。
最簡單的就是當我們使用 COUNT(*) 的時候,這種情況下通配符 * 并不像我們猜想的那樣擴展成所有的列,實際上,他會忽略所有列而直接統計所有的行數。
——《高性能MySQL》
不管怎樣,我們判斷是否存在。只需確定,有和無,而不是,無還是有多少!在有的情況下,直接返回,而不需要繼續統計行數!
巧妙的使用 LIMIT 1,獲得更高效率,尤其是在某些復雜且不規范的語句中效果更明顯!
作者:程序猿囧途
編輯:陶家龍
出處:toutiao.com/i6826511837840802315