MySQL查詢優化之COUNT

2021-07-04 06:58:24 字數 1765 閱讀 7256

count()聚合函式,以及如何優化使用了該函式的查詢,很可能是mysql中最容易被誤解的前10個話題之一,在網上隨便搜尋一下就能看到很多錯誤的理解,可能比我們想象的多得多。

在做優化之前,先來看看count()函式的真正作用是什麼。

count()的作用

count()的另外乙個作用是統計結果集的行數。當mysql確認括號內的表示式值不可能為空時,實際上就是在統計行數。最簡單的就是當我們使用count(*)的時候,這種情況下萬用字元*並不會像我們猜想的那樣擴充套件成所有的列,實際上,它會忽略所有的列而直接統計所有的行數。

我們發現乙個最常見的錯誤就是,在括號內指定了乙個列卻希望統計結果集的行數。如果希望知道的是結果集的行數,最好使用count(*),這樣寫意義清晰,效能也會很好。

關於myisam的神話

乙個容易產生的誤解就是:myisam的count()函式總是非常快,不過這是有前提條件的,即只有沒有任何where條件的count(*)才非常快,因為此時無需實際地去計算表的行數。mysql可以利用儲存引擎的特性直接獲得這個值。如果mysql知道某列col不可能為null值,那麼mysql內部會將count(col)表示式優化為count(*)。

當統計帶where子句的結果集行數,可以是統計某個列值的數量時,mysql的count()和其它儲存引擎沒有任何不同,就不再有神話般的速度了。所以在myisam引擎表上執行count()有時候比別的引擎快,有時候比別的引擎慢,這受很多因素影響,要視具體情況而定。

簡單的優化

有時候可以使用myisam在count()全表非常快的這個特性,來加速一些特定條件count()的查詢。在下面的例子中,我們使用標準資料庫world來看看如何快速查詢到所有id大於5的城市。可以像下面這樣來寫這個查詢:

mysql>select

count(*) from world.city where id > 5;

通過show status的結果可以看到該查詢需要掃瞄4097行資料。如果將條件反轉一下,先查詢id小於等於5的城市數,然後用總城市數一減就能得到同樣的結果,卻可以將掃瞄的行數減少到5行以內:

mysql>select (select

count(*) from world.city) - count(*) from world.city where id <= 5;

這樣做可以大大減少需要掃瞄的行數,是因為在查詢優化階段會將其中的子查詢直接當成乙個常數來處理,我們可以通過explain來驗證這點。

在郵件組和irc聊天頻道中,通常會看到這樣的問題:如果在同乙個查詢中統計同乙個列的不同值的數量,以減少查詢的語句量。例如,假設可能需要通過乙個查詢返回各種不同顏色的商品數量,此時不能使用or語句,因為這樣做就無法區分不同顏色的商品數量。下面的查詢可以在一定程度上解決這個問題。

mysql>select

sum(if(color = 'blue', 1, 0)) as blue,sum(if(color = 'red', 1, 0)) as red from items;

也可以使用count()而不是sum()實現同樣的目的,只需要將滿足條件設定為真,不滿足條件設定為null即可:

mysql>select

count(color = 'blue'

ornull) as blue,count(color = 'red'

ornull) as red from items;

MySQL優化之COUNT 效率

說到mysql的count 的效率,發現越說越說不清楚,乾脆寫下來,分享給大家。count 與count col 網上搜尋了下,發現各種說法都有 比如認為count col 比count 快的 認為count 比count col 快的 還有朋友很搞笑的說到這個其實是看人品的。在不加where限制條...

MySQL優化之COUNT 效率

count 與count col 網上搜尋了下,發現各種說法都有 比如認為count col 比count 快的 認為count 比count col 快的 還有朋友很搞笑的說到這個其實是看人品的。在不加where限制條件的情況下,count 與count col 基本可以認為是等價的 但是在有wh...

mysql的count函式優化

mysql的count優化總體上有以下注意事項 1.任何情況下select count from tablename是最優選擇 2.儘量減少select count from tablename where col value 這種查詢 3.杜絕select count col from table...