自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用Select * 進(jìn)行SQL查詢(xún)的七宗罪

譯文
數(shù)據(jù)庫(kù) Oracle
本文通過(guò)在應(yīng)用編程中的實(shí)際經(jīng)驗(yàn),向大家證明使用Select * from table進(jìn)行SQL查詢(xún)的“七宗罪”。

【51CTO.com快譯】如今,網(wǎng)上許多文章都已明確地指出:使用“SELECT * ”作為SQL查詢(xún)方式是一種極其危險(xiǎn)的代碼書(shū)寫(xiě)習(xí)慣。開(kāi)發(fā)人員應(yīng)該盡量在自己的程序中避免出現(xiàn)此類(lèi)查詢(xún),取而代之的應(yīng)該是明確地指定要查詢(xún)的列名。不過(guò),大家可能只是“知其然,而不知其所以然”。在本文中,讓我向各位初級(jí)開(kāi)發(fā)人員詳細(xì)解釋?zhuān)祟?lèi)SQL查詢(xún)***實(shí)踐背后的具體原因。

首先,我們經(jīng)常面對(duì)的客觀(guān)情況是:在Oracle數(shù)據(jù)庫(kù)中,許多SQL開(kāi)發(fā)人員都是從接觸“SELECT * from EMP”(EMP為表的名稱(chēng))之類(lèi)的查詢(xún)語(yǔ)句,開(kāi)始學(xué)習(xí)SQL語(yǔ)言的。因此,除非能夠給出充分的理由,否則我們很難撼動(dòng)他們使用此類(lèi)便捷查詢(xún)語(yǔ)句的習(xí)慣。

下面,我將根據(jù)自己在應(yīng)用編程中的實(shí)際經(jīng)驗(yàn),向大家證明使用Select * from table進(jìn)行SQL查詢(xún)的“七宗罪”。

1. 不必要的I/O(輸入/輸出)

通過(guò)使用SELECT * ,您雖然可以獲得一些完全可以被忽略的返回?cái)?shù)據(jù),但是該獲取過(guò)程可并不是免費(fèi)的。那些本來(lái)可能只需要從索引頁(yè)面中讀取的數(shù)據(jù)檢索,如今您卻不得不從各個(gè)頁(yè)面中以全量的方式讀取出來(lái)。顯然,此舉會(huì)導(dǎo)致數(shù)據(jù)庫(kù)端白白浪費(fèi)各種有限的I/O周期。

另外,該方式也可能會(huì)拖慢您的查詢(xún)速度。如果您好奇并想探究數(shù)據(jù)庫(kù)后臺(tái)的查詢(xún)執(zhí)行過(guò)程,以及查詢(xún)引擎是如何順次處理查詢(xún)語(yǔ)句的話(huà),我建議您參考:Markus Winand的《SQL Performance Explained》(請(qǐng)參見(jiàn)http://www.amazon.com/Performance-Explained-Everything-Developers-about/dp/3950307826/?tag=javamysqlanta-20),以及Udemy的《The Complete SQL BootCamp》(請(qǐng)參見(jiàn)https://click.linksynergy.com/fs-bin/click?id=JVFxdTr9V80&subid=0&offerid=323058.1&type=10&tmpid=14538&RD_PARM1=https%3A%2F%2Fwww.udemy.com%2Fthe-complete-sql-bootcamp%2F)課程。

2. 增加的網(wǎng)絡(luò)流量

SELECT * 雖然能返回比用戶(hù)預(yù)期更多的數(shù)據(jù),但是相應(yīng)地,這些數(shù)據(jù)的傳輸勢(shì)必會(huì)消耗更多的網(wǎng)絡(luò)帶寬資源。與此同時(shí),網(wǎng)絡(luò)帶寬的增加也就意味著:那些真正為用戶(hù)所需要的數(shù)據(jù)將會(huì)花費(fèi)更長(zhǎng)的時(shí)間,才能被傳送到客戶(hù)端的應(yīng)用程序上。例如:如果您可能是在本地計(jì)算機(jī)上運(yùn)行由SQL Server Management Studio(請(qǐng)?jiān)斠?jiàn)http://bit.ly/2CXPyBB)、Toad或SQL Developer for Oracle(請(qǐng)參見(jiàn)http://bit.ly/2xQzAsd)提供的查詢(xún)編輯器,或是在某個(gè)Java應(yīng)用服務(wù)器上運(yùn)行此類(lèi)查詢(xún),這都會(huì)耗費(fèi)您不少的網(wǎng)絡(luò)流量與資源。

3.更多的應(yīng)用內(nèi)存

隨著業(yè)務(wù)數(shù)據(jù)的猛增,您的應(yīng)用程序可能需要使用更多的內(nèi)存,來(lái)保存由此類(lèi)查詢(xún)方式所產(chǎn)生的,可能來(lái)自Microsoft SQL Server(請(qǐng)參見(jiàn)http://www.java67.com/2018/01/top-4-free-microsoft-sql-server-books.html)的各種無(wú)用數(shù)據(jù)。

4.產(chǎn)生依賴(lài)于列排序的結(jié)果集(ResultSet)

當(dāng)您在應(yīng)用程序中使用SELECT * 查詢(xún)后,您會(huì)得到一些依賴(lài)于數(shù)據(jù)表的列排序的結(jié)果集。因此,一旦有新的列被添加,或者是列排序被修改了,它們都會(huì)對(duì)查詢(xún)的結(jié)果集產(chǎn)生不同的影響。

5.新增列會(huì)破壞既有的視圖

如果您在視圖(請(qǐng)參見(jiàn)http://www.java67.com/2012/11/what-is-difference-between-view-vs-materialized-view-database-sql.html)中使用了SELECT * ,那么一旦有新的列被添加,同時(shí)舊的列從表中被去除時(shí),您所構(gòu)建的原有視圖就會(huì)被破壞,進(jìn)而返回給用戶(hù)錯(cuò)誤的結(jié)果。

為避免此類(lèi)情況的發(fā)生,您應(yīng)該始終在SQL Server數(shù)據(jù)庫(kù)(請(qǐng)參見(jiàn)http://javarevisited.blogspot.sg/2013/11/difference-between-char-varchar-nchar-nvarchar-sql-database.html#axzz5CSnhvSWV)里,對(duì)于視圖的定義中,包含WITH SCHEMABINDING選項(xiàng)。

6. 連接查詢(xún)中的沖突

如果您在連接查詢(xún)(JOIN Query,請(qǐng)參見(jiàn)https://javarevisited.blogspot.com/2012/11/how-to-join-three-tables-in-sql-query-mysql-sqlserver.html#axzz5az3hfsHW)中使用了SELECT * ,那么一旦在多個(gè)表中出現(xiàn)了具有相同名稱(chēng)的列,例如status、active和name等,就可能會(huì)產(chǎn)生各種并發(fā)式的沖突。

雖說(shuō)在直接查詢(xún)中,出現(xiàn)問(wèn)題的可能性不大,但是當(dāng)您試著按其中的某一列進(jìn)行排序、或是在公用表表達(dá)式(Common Table Expression,CTE)、以及派生表(derived table)中使用查詢(xún)的時(shí)候,您就需要進(jìn)行各種進(jìn)一步的調(diào)整,以避免產(chǎn)生沖突了。

7.在表間復(fù)制數(shù)據(jù)時(shí)的風(fēng)險(xiǎn)

您可能會(huì)經(jīng)常使用“SELECT * into INSERT . . .”之類(lèi)的語(yǔ)句,以實(shí)現(xiàn)將某些數(shù)據(jù)從一張表復(fù)制到另一張表。如果在兩張表中,各個(gè)列的排列順序略有不同,那么就可能會(huì)出現(xiàn)將不正確的數(shù)據(jù)復(fù)制到錯(cuò)誤列中的情況。

一些程序員可能會(huì)認(rèn)為:由于查詢(xún)解析器必須額外地驗(yàn)證某些靜態(tài)值,因此導(dǎo)致了在EXISTS語(yǔ)句(譯者注:即檢驗(yàn)查詢(xún)的結(jié)果是否返回?cái)?shù)據(jù),請(qǐng)參見(jiàn)https://javarevisited.blogspot.com/2016/01/sql-exists-example-customers-who-never-ordered.html)中使用SELECT * 要比SELECT 1的速度更快一些。此觀(guān)點(diǎn)擱在過(guò)去可能會(huì)有幾分道理。但是現(xiàn)在,各種數(shù)據(jù)庫(kù)解析器已經(jīng)發(fā)展得相當(dāng)智能了,它們判斷EXISTS語(yǔ)句的效率,與產(chǎn)生SELECT結(jié)果列表(請(qǐng)參見(jiàn)https://javarevisited.blogspot.com/2016/04/how-to-convert-result-of-select-command-to-comma-separated-String-in-SQL-Server.html)將毫無(wú)關(guān)系。

結(jié)論

通過(guò)上述七點(diǎn)分析,相信您應(yīng)該明白了為什么不能在SQL查詢(xún)中濫用SELECT * 的原因吧?可見(jiàn),您應(yīng)該盡可能地在查詢(xún)中,使用顯式的列名稱(chēng),而不是那些星號(hào)通配符。此舉不但能夠提高您的代碼效率,也可以使您的程序更加清晰。與此同時(shí),該方法還能夠幫助您創(chuàng)建各種具有可維護(hù)性的代碼。而且,如果后期在表中有新的一列被添加的話(huà),您的代碼也不會(huì)因此受到影響,您仍然會(huì)擁有來(lái)自原始數(shù)據(jù)表的參考視圖。

原文標(biāo)題:7 Reasons Why Using SELECT * FROM TABLE in SQL Query Is a Bad Idea,作者:Javin Paul

【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】

責(zé)任編輯:龐桂玉 來(lái)源: 51CTO
相關(guān)推薦

2023-05-08 10:54:39

IT管理CIO

2024-06-19 19:28:51

2018-02-05 23:14:35

光纖網(wǎng)絡(luò)光纖施工

2011-02-21 09:04:25

2014-01-13 09:35:13

創(chuàng)業(yè)企業(yè)

2021-03-01 18:48:21

Go管理工具

2013-01-17 17:14:52

Objective-C

2013-05-10 10:49:53

2015-09-15 13:22:08

數(shù)據(jù)分析七宗罪

2010-08-18 10:05:27

IE7IE6

2011-02-23 10:51:36

Chrome

2021-03-03 14:08:48

自動(dòng)化高管IT投資

2012-04-04 22:15:19

移動(dòng)游戲

2012-09-07 14:41:26

2015-07-16 09:14:50

數(shù)據(jù)中心數(shù)據(jù)中心效率

2023-10-17 20:28:13

軟件開(kāi)發(fā)代碼

2016-12-08 13:12:36

數(shù)據(jù)中心綠色認(rèn)證

2017-01-09 15:25:49

物聯(lián)網(wǎng)策略設(shè)計(jì)

2017-08-02 16:24:04

2015-09-06 11:25:57

七宗罪失敗案例
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)