【原創】Mysql中select的正確姿勢


引言

大家在開發中,還有很多童鞋在寫查詢語句的時候,習慣寫下面這種不規范sql

select * from table

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

select col1,col2,...,coln from table

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

你:“xx,知道select *和select所有字段的區別么?
同事:"額。。額。。額。。"
留下的只有尷尬的笑容!

我也知道,很多人至今都沒有搞懂select *selct 所有字段的區別
因此,我開一文來說明一下。另外,我選的是自己最熟悉的mysql數據庫,此文的結論在oralce,sqlserver上是否成立,博主沒做過測試。

正文

(select所有字段)性能高?

網絡上流傳着一種說法說是

“*” 表示通配所有字段,在SQL的機制里,需要先識別統計所有字段再進行下一步。
明確指定字段的話,會減少上述的操作,所以效率有所提升。

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

SELECT * FROM `dmsp`.`dmsp_dimension_content` LIMIT 0, 1000;  

時間2.218s,網絡消耗0.547s

SELECT `id`, `appid`, `aop`, `t`, `uid`, `sid`, `pid`, `pname`, `bid`, `bname`, `ptype`, `sm`, `sv`, `bt`, `national`, `area`, `ov` FROM `dmsp`.`dmsp_dimension_content` LIMIT 0, 1000;  

取出所有字段,時間2.250s,網絡消耗0.578s
可以看出,這二者的時間差幾乎可以忽略,另外還有一本書上的內容也可以佐證我的話。
《SQL CookBook》第一章 檢索記錄中1.1小節(原書第十五頁內容如下):
image
此書也說明了,兩種方式在性能上幾乎是沒有差距的。
那為什么還是不推薦select * ?

網絡IO問題

很多文章里說什么,會帶來額外的內存、磁盤、cpu的開銷。對此,我有自己的觀點。我覺得這不是主要原因。主要原因是帶來了額外的網絡開銷。
在一個系統中,內存、磁盤、cpu的開銷,不過是微妙級。造成系統的延遲的重頭戲是網絡開銷。網絡開銷可能帶來秒級的延遲。當然,如果你的應用程序和數據庫是在同一台機器上的,那當我沒說這句話!
select *會查詢出不需要的、額外的數據,那么這些額外的數據在網絡上進行傳輸,必定會造成性能延遲。假設你的table中,有一個列的類型為binary。此時,你的select *操作,就會十分緩慢,並且會造成額外的網絡開銷。

索引問題

仔細看下面的兩句sql

select col1 from table;
select * from table;

如果col1字段包含索引信息,那么此時,這兩句的sql執行時間可能會有幾十上百倍的差異。
在col1字段有索引的情況下,mysql是可以不用讀data,直接使用index里面的值就返回結果的。但是一旦用了select *,就會有其他列需要讀取,這時在讀完index以后還需要去讀data才會返回結果。這樣就造成了額外的性能開銷。

ps:我不想在這里扯什么覆蓋索引,輔助索引的概念。其實要講的很專業,扯一堆高大上的名詞,我也可以。只是這樣徒增讀者的理解難度,盡量用通俗的方式來講。

擴展性問題

有的人會覺得

使用select * ,這樣在增加列的時候,不用改sql,方便!

然而實際上,你的sql是不用改了,但是對你的程序代碼是有很大的影響的!
身為一名21世紀的優良程序員,我們是不能獲取自己需要的東西的!你因為一時高興,執行了select *,如果增加或刪除列,會對你的代碼有着極大的影響。
反過來,如果你select 指定列,只獲取自己需要的幾列,表結構的修改,對你代碼的影響就會小很多。相比之下,風險就沒有那么大了!
另外就是,對於其他人接手你項目的人來說,看到select 指定列的方式,可讀性更強,對於他們來說更好上手!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM