爲什麼SELECT * 查詢效率低

看着你滿懷期待的臉
不經意間
衝破了我對你的平淡
心頭一酸
內心又有點波瀾
這是否存在隱患
還是暗示某種慘淡

關於MYSQL語句優化的問題,老生常談,什麼儘量避免使用SELECT * ,儘量避免條件使用or,加上limit限制行數…

就在上週,公司的一個項目,功能是在發佈文章時不發佈保存草稿後,打開草稿重新發布時,地區的name不顯示的BUG,主管讓我排查了代碼,原來是在寫sql語句時沒有對地區name的字段進行查詢。
這時候我勤勞的優點就展現出來了,把那幾個字段加上就好了,雖然腦海裏浮現出了一個小星星,沒錯,就是你想的那個小星星。哎呀,真香!(我們公司項目不是很大,數據量也上不去,性能上還沒有遇到瓶頸,所以比較放縱哈)

大家不要學我哈,代碼優化的必要性還是非常重要的。

效率低?

首先我們先看一下最新發布的《阿里JAVA開發手冊泰山版》中是這樣說的

關注文末公衆號,回覆 ‘’手冊‘’ ,可獲取阿里JAVA開發手冊最新版

在這裏插入圖片描述

增加查詢分析器解析成本

MYSQL在執行查詢語句需要經過很多階段的處理,拿到數據也會進行一些處理,這裏不過多瞭解。
而你給出實際需要查詢的字段,mysql內部會針對你所查詢的字段進行必要優化處理,而查詢所有字段在mysql內部雖然也會優化,但優化方案可能會針對其他不需要的字段進行優化處理,效率定然會有所差異。
在這裏插入圖片描述

增減字段容易與resultMap配置不一致

這個就比較好理解了,相信用過ORM(對象關係映射)的框架的夥伴們秒懂,使用 * 自然需要實體類和數據庫字段一一對應(或者進行一一對應的配置)方能舒服的使用。

無用字段增加網絡消耗

不需要的字段會增加數據傳輸時間和網絡開銷

用 SELECT * 的話,數據庫需要解析更多的對象,字段,權限,屬性等相關內容,在SQL語句複雜,硬解析解析較多的情況下,會對數據庫造成沉重的負擔。

增加網絡開銷

有時會誤帶上入log,lconMD5之類的無用且大文本大內容字段,數據傳輸size會幾何增漲。如果DB和應用程序不在同一個服務器,進行數據傳輸的開銷就不用多說了吧

即使 mysql 服務器和客戶端是在同一臺機器上,使用的協議還是 tcp,通信也是需要額外的時間。

IO操作

對於無用的大字段,如 varchar、blob、text,會增加 io 操作
準確來說,長度超過 728 字節的時候,會先把超出的數據序列化到另外一個地方,因此讀取這條記錄會增加一次 io 操作。(MySQL InnoDB)

"覆蓋索引"失效

SELECT * 杜絕了覆蓋索引的可能性,而基於MYSQL優化器的“覆蓋索引”策略又是速度極快,效率極高,業界極爲推薦的查詢優化方式。

例如,有一個表爲t(a,b,c,d,e,f),其中,a爲主鍵,b列有索引。

那麼,在磁盤上有兩棵 B+ 樹,即聚集索引和輔助索引(包括單列索引、聯合索引),分別保存(a,b,c,d,e,f)和(a,b),如果查詢條件中where條件可以通過b列的索引過濾掉一部分記錄,查詢就會先走輔助索引,如果用戶只需要a列和b列的數據,直接通過輔助索引就可以知道用戶查詢的數據。

如果用戶使用select *,獲取了不需要的數據,則首先通過輔助索引過濾數據,然後再通過聚集索引獲取所有的列,這就多了一次b+樹查詢,速度必然會慢很多。

在這裏插入圖片描述
由於輔助索引的數據比聚集索引少很多,很多情況下,通過輔助索引進行覆蓋索引(通過索引就能獲取用戶需要的所有列),都不需要讀磁盤,直接從內存取,而聚集索引很可能數據在磁盤(外存)中(取決於buffer pool的大小和命中率),這種情況下,一個是內存讀,一個是磁盤讀,速度差異就很顯著了,幾乎是數量級的差異。

MYSQL設計了這麼好的覆蓋索引,我們還是要對的起MYSQL的良苦用心的哈

索引是建的越多越好嗎

答案自然是否定的

  1. 數據量小的表不需要建立索引,建立會增加額外的索引開銷
  2. 不經常引用的列不要建立索引,因爲不常用,即使建立了索引也沒有多大意義
  3. 經常頻繁更新的列不要建立索引,因爲肯定會影響插入或更新的效率
  4. 數據重複且分佈平均的字段,因此他建立索引就沒有太大的效果(例如性別字段,只有男女,不適合建立索引)
  5. 數據變更需要維護索引,意味着索引越多維護成本越高。
  6. 更多的索引也需要更多的存儲空間

部分摘選自博客—>>>_陳哈哈

文章持續更新,可以微信搜索「 紳堂Style 」第一時間閱讀,回覆【資料】有我準備的面試題筆記。
GitHub https://github.com/dtt11111/Nodes 有總結面試完整考點、資料以及我的系列文章。歡迎Star。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章