Mysql基礎知識整理筆記(疑問整理)

此篇主要整理基礎篇中的疑問
PS:文章整理的知識內容及資料均來自極客時間《SQL必知必會》專欄優化

一、在MySQL統計行數中,SELECT COUNT(*)SELECT COUNT(1)SELECT COUNT(具體字段)的查詢效率具體如何?

在MySQL InnoDB存儲引擎中,COUNT(*)COUNT(1)都是對全部結果進行COUNT。若是有WHERE子句,則是對數據表的數據行數進行統計。所以COUNT(*)COUNT(1)本質上並無區別,執行的複雜度都是O(N),也就是採用全表掃描,進行循環 + 計數的方式進行統計。code

在MySQL MyISAM 存儲引擎,統計數據表的行數只須要O(1)的複雜度,這是由於每張 MyISAM 的數據表都有一個 meta 信息存儲了row_count值,而一致性則由表級鎖來保證。由於 InnoDB 支持事務,採用行級鎖和 MVCC 機制,因此沒法像 MyISAM 同樣,只維護一個row_count變量,所以須要採用掃描全表,進行循環 + 計數的方式來完成統計。排序

另外在 InnoDB 引擎中,若是採用COUNT(*)COUNT(1)來統計數據行數,要儘可能採用二級索引。由於主鍵採用的索引是聚簇索引,聚簇索引包含的信息多,明顯會大於二級索引(非聚簇索引)。對於COUNT(*)COUNT(1)來講,它們不須要查找具體的行,只是統計行數,系統會自動採用佔用空間更小的二級索引來進行統計。索引

總結:
一、列名爲主鍵, count(列名)count(1)count(*)執行效率是同樣的:由於 explain 中 type 類型都爲 index
二、列名不爲主鍵,並且列名沒有建立索引可是其餘字段建立了索引: count(1) = count(*) > count(列名);因
爲expalin 中的 type 類型 count(1)  和 count(*) 類型都爲 index  而 count(列名) 的 type 類型爲 all
三、列名不爲主鍵,可是列名建立索引: count(1) = count(*)= count(列名);由於 explain 中 type 類型都爲 index
四、若是表多個列而且沒有主鍵,則 count(1) = count(*) 
五、若是表只有一個字段,則 select count(*)和  select count(1) 和  select count(列名)執行效率同樣。

二、在MySQL中,LIMIT 關鍵詞是最後執行的,若是確認結果集就只有一條,爲什麼還需加上LIMIT 1進行優化?

若是你能夠肯定結果集只有一條,那麼加上LIMIT 1的時候,當找到一條結果的時候就不會繼續掃描了,這樣會加快查詢速度。若是數據表已經對字段創建了惟一索引,那麼能夠經過索引進行查詢,不會全表掃描的話,就不須要加上LIMIT 1了。事務

三、 在WHERE子句中加索引能夠快速定位數據,那爲何須要在ORDER BY字段中也加上索引?

在 MySQL 中,支持兩種排序方式,分別是 FileSort 和 Index 排序。在 Index 排序中,索引能夠保證數據的有序性,不須要再進行排序,效率更高。而 FileSort 排序則通常在內存中進行排序,佔用 CPU 較多。若是待排結果較大,會產生臨時文件 I/O 到磁盤進行排序的狀況,效率較低。因此使用 ORDER BY 子句時,應該儘可能使用 Index 排序,避免使用 FileSort 排序。固然你可使用 explain 來查看執行計劃,看下優化器是否採用索引進行排序。內存

四、 ORDER BY 是對分的組排序仍是對分組中的記錄排序呢?

ORDER BY 就是對記錄進行排序。若是你在 ORDER BY 前面用到了 GROUP BY,實際上這是一種分組的聚合方式,已經把一組的數據聚合成爲了一條記錄,再進行排序的時候,至關於對分的組進行了排序。效率

相關文章
相關標籤/搜索