mysql中使用select的正確姿勢你知道嗎?
引言
大家在開發中,還有很多童鞋在寫查詢語句的時候,習慣寫下面這種 不規範 sql

而不寫成下面的這種 規範 方式

我也知道,這些童鞋是圖方便,畢竟再敲一堆的列名,嫌麻煩!
你們上班可以問問自己的同事

我也知道,很多人至今都沒有搞懂select *和selct 所有欄位的區別
因此,我開一文來說明一下。另外,我選的是自己最熟悉的mysql資料庫,此文的結論在oralce,sqlserver上是否成立,博主沒做過測試。
正文
(select所有欄位)效能高?
網路上流傳著一種說法說是

然而,實際上呢?效率是相差不大的!。
取部落格
http://flysnowxf.iteye.com/blog/1125032
的測試結果
mysql 5.1.37
表記錄數41,547,002,即4000w行
使用遠端客戶端取1000條資料,統計時間:

時間2.218s,網路消耗0.547s

取出所有欄位,時間2.250s,網路消耗0.578s
可以看出,這二者的時間差幾乎可以忽略,另外還有一本書上的內容也可以佐證我的話。
《SQL CookBook》第一章 檢索記錄中1.1小節(原書第十五頁內容如下):

此書也說明了,兩種方式在效能上幾乎是沒有差距的。
那為什麼還是不推薦select * ?
網路IO問題
很多文章裡說什麼,會帶來額外的記憶體、磁碟、cpu的開銷。對此,我有自己的觀點。我覺得這不是主要原因。主要原因是帶來了額外的網路開銷。
在一個系統中,記憶體、磁碟、cpu的開銷,不過是微秒級。造成系統的延遲的重頭戲是網路開銷。網路開銷可能帶來秒級的延遲。當然,如果你的應用程式和資料庫是在同一臺機器上的,那當我沒說這句話!
select *會查詢出不需要的、額外的資料,那麼這些額外的資料在網路上進行傳輸,必定會造成效能延遲。假設你的table中,有一個列的型別為binary。此時,你的select *操作,就會十分緩慢,並且會造成額外的網路開銷。
索引問題
仔細看下面的兩句sql

如果col1欄位包含索引資訊,那麼此時,這兩句的sql執行時間可能會有幾十上百倍的差異。
在col1欄位有索引的情況下,mysql是可以不用讀data,直接使用index裡面的值就返回結果的。但是一旦用了select *,就會有其他列需要讀取,這時在讀完index以後還需要去讀data才會返回結果。這樣就造成了額外的效能開銷。
ps:我不想在這裡扯什麼覆蓋索引,輔助索引的概念。其實要講的很專業,扯一堆高大上的名詞,我也可以。只是這樣徒增讀者的理解難度,儘量用通俗的方式來講。
擴充套件性問題
有的人會覺得

然而實際上,你的sql是不用改了,但是對你的程式程式碼是有很大的影響的!
身為一名21世紀的優良程式設計師,我們是不能獲取自己需要的東西的!你因為一時高興,執行了select *,如果增加或刪除列,會對你的程式碼有著極大的影響。
反過來,如果你select 指定列,只獲取自己需要的幾列,表結構的修改,對你程式碼的影響就會小很多。相比之下,風險就沒有那麼大了!
另外就是,對於其他人接手你專案的人來說,看到select 指定列的方式,可讀性更強,對於他們來說更好上手!
歡迎工作一到五年的Java工程師朋友們加入Java填坑之路:860113481
群內提供免費的Java架構學習資料(裡面有高可用、高併發、高效能及分散式、Jvm效能調優、Spring原始碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!