常見誤解
count(1)和count(primary_key) 優於count(*)
很多人為了統計記錄條數,就使用count(1) 和count(primary_key) 而不是count(*) ,他們認為這樣效能更好,其實這是一個誤解。對於有些場景,這樣做可能效能會更差,並且應為資料庫對 count(*) 計數操作做了一些特別的最佳化。
count(column) 和count(*) 是一樣的
這個迷思甚至在很多的資深工程師或者是DBA 中都普遍存在,很多人都會認為這是理所當然的。實際上,count(column) 和 count(*) 是一個完全不一樣的操作,所代表的意義也完全不一樣。
count(column) 是表示結果集中有多少個column欄位不為空的記錄
count(*) 是表示整個結果集有多少筆記錄
select a,b from … 比select a,b,c from … 可以讓資料庫存取更少的資料量
這個誤解主要存在於大量的開發人員中,主要原因是對資料庫的儲存原理不是太了解。
實際上,大多數關係型資料庫都是按照行(row)的方式存儲,而資料存取操作都是以一個固定大小的IO單元(被稱為block 或page)為單位,一般為4KB,8KB… 大多數時候,每個IO單元中儲存了多行,每行都是儲存了該行的所有欄位(lob等特殊類型欄位除外)。
所以,我們是取一個字段還是多個字段,實際上資料庫在表中需要存取的資料量其實是一樣的。
當然,也有例外情況,那就是我們的這個查詢在索引中就可以完成,也就是說當只取a,b兩個欄位的時候,不需要回表,而c這個欄位不在使用的索引中,需要回表取得其資料。在這樣的情況下,二者的IO量會有較大差異。
order by 一定需要排序操作
我們知道索引資料其實是有順序的,如果我們的所需的資料和某個索引的順序一致,而且我們的查詢又透過這個索引來執行,那麼資料庫一般會省略排序操作,而直接將資料傳回,因為資料庫知道資料已經滿足我們的排序需求了。
實際上,利用索引來最佳化排序需求的SQL,是一個非常重要的最佳化手段
延伸閱讀:MySQL ORDER BY 的實作分析 ,MySQL 中GROUP BY 基本實作原理 以及MySQL DISTINCT 的基本實作原理 這3篇文章中有更深入的分析,尤其是第一篇
執行計畫中有filesort 就會進行磁碟檔案排序
有這個誤解其實不能怪我們,而是因為MySQL 開發者在用詞上的問題。 filesort 是我們在使用 explain 指令查看一條 SQL 的執行計劃的時候可能會看到在 “Extra” 一列顯示的資訊。
實際上,只要一條 SQL 語句需要進行排序操作,都會顯示“Using filesort”,這並不表示就會有檔案排序操作。
延伸閱讀:理解 MySQL Explain 指令輸出中的filesort,我在這裡有更詳細的介紹
盡量少join
MySQL 的優點在於簡單,但這在某些方面其實也是其劣勢。 MySQL 優化器效率高,但由於其統計資訊的量有限,優化器工作過程出現偏差的可能性也更多。對於複雜的多表 Join,一方面由於其優化器受限,再者在 Join 這方面所下的功夫還不夠,所以性能表現離 Oracle 等關係型資料庫前輩還是有一定距離。但如果是簡單的單表查詢,這一差距就會極小甚至在有些場景下要優於這些資料庫前輩。
盡量少排序
#排序作業會消耗較多的CPU 資源,所以減少排序可以在快取命中率高等IO 能力足夠的場景下會較大影響SQL 的反應時間。
對於MySQL來說,減少排序有多種辦法,例如:
上面誤區中提到的透過利用索引來排序的方式進行最佳化
#減少參與排序的記錄條數
#非必要不對資料排序
避免使用耗費資源的操作,具有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語句會啟動SQL引擎執行,耗費資源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要執行兩次排序
#
以上是Mysq的一些常見誤解的詳細內容。更多資訊請關注PHP中文網其他相關文章!