会员登录 - 用户注册 - 设为首页 - 加入收藏 - 网站地图 用Select * 进行SQL查询的七宗罪!

用Select * 进行SQL查询的七宗罪

时间:2025-11-05 11:43:46 来源:益强数据堂 作者:数据库 阅读:785次

【.com快译】如今,查询网上许多文章都已明确地指出:使用“SELECT * ”作为SQL查询方式是查询一种极其危险的代码书写习惯。开发人员应该尽量在自己的查询程序中避免出现此类查询,取而代之的查询应该是明确地指定要查询的列名。不过,查询大家可能只是查询“知其然,而不知其所以然”。查询在本文中,查询让我向各位初级开发人员详细解释,查询此类SQL查询***实践背后的查询具体原因。

首先,查询我们经常面对的查询客观情况是:在Oracle数据库中,许多SQL开发人员都是查询从接触“SELECT * from EMP”(EMP为表的名称)之类的查询语句,开始学习SQL语言的查询。因此,查询除非能够给出充分的理由,否则我们很难撼动他们使用此类便捷查询语句的习惯。

下面,企商汇我将根据自己在应用编程中的实际经验,向大家证明使用Select * from table进行SQL查询的“七宗罪”。

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

通过使用SELECT * ,您虽然可以获得一些完全可以被忽略的返回数据,但是该获取过程可并不是免费的。那些本来可能只需要从索引页面中读取的数据检索,如今您却不得不从各个页面中以全量的方式读取出来。显然,此举会导致数据库端白白浪费各种有限的I/O周期。

另外,该方式也可能会拖慢您的查询速度。如果您好奇并想探究数据库后台的查询执行过程,以及查询引擎是如何顺次处理查询语句的话,我建议您参考:Markus Winand的《SQL Performance Explained》(请参见http://www.amazon.com/Performance-Explained-Everything-Developers-about/dp/3950307826/?tag=javamysqlanta-20),以及Udemy的《The Complete SQL BootCamp》(请参见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. 增加的网络流量

SELECT * 虽然能返回比用户预期更多的服务器托管数据,但是相应地,这些数据的传输势必会消耗更多的网络带宽资源。与此同时,网络带宽的增加也就意味着:那些真正为用户所需要的数据将会花费更长的时间,才能被传送到客户端的应用程序上。例如:如果您可能是在本地计算机上运行由SQL Server Management Studio(请详见http://bit.ly/2CXPyBB)、Toad或SQL Developer for Oracle(请参见http://bit.ly/2xQzAsd)提供的查询编辑器,或是在某个Java应用服务器上运行此类查询,这都会耗费您不少的网络流量与资源。

3.更多的应用内存

随着业务数据的猛增,您的应用程序可能需要使用更多的内存,来保存由此类查询方式所产生的,可能来自Microsoft SQL Server(请参见http://www.java67.com/2018/01/top-4-free-microsoft-sql-server-books.html)的各种无用数据。

4.产生依赖于列排序的结果集(ResultSet)

当您在应用程序中使用SELECT * 查询后,网站模板您会得到一些依赖于数据表的列排序的结果集。因此,一旦有新的列被添加,或者是列排序被修改了,它们都会对查询的结果集产生不同的影响。

5.新增列会破坏既有的视图

如果您在视图(请参见http://www.java67.com/2012/11/what-is-difference-between-view-vs-materialized-view-database-sql.html)中使用了SELECT * ,那么一旦有新的列被添加,同时旧的列从表中被去除时,您所构建的原有视图就会被破坏,进而返回给用户错误的结果。

为避免此类情况的发生,您应该始终在SQL Server数据库(请参见http://javarevisited.blogspot.sg/2013/11/difference-between-char-varchar-nchar-nvarchar-sql-database.html#axzz5CSnhvSWV)里,对于视图的定义中,包含WITH SCHEMABINDING选项。

6. 连接查询中的冲突

如果您在连接查询(JOIN Query,请参见https://javarevisited.blogspot.com/2012/11/how-to-join-three-tables-in-sql-query-mysql-sqlserver.html#axzz5az3hfsHW)中使用了SELECT * ,那么一旦在多个表中出现了具有相同名称的列,例如status、active和name等,就可能会产生各种并发式的冲突。

虽说在直接查询中,出现问题的可能性不大,但是当您试着按其中的某一列进行排序、或是在公用表表达式(Common Table Expression,CTE)、以及派生表(derived table)中使用查询的时候,您就需要进行各种进一步的调整,以避免产生冲突了。

7.在表间复制数据时的风险

您可能会经常使用“SELECT * into INSERT . . .”之类的语句,以实现将某些数据从一张表复制到另一张表。如果在两张表中,各个列的排列顺序略有不同,那么就可能会出现将不正确的数据复制到错误列中的情况。

一些程序员可能会认为:由于查询解析器必须额外地验证某些静态值,因此导致了在EXISTS语句(译者注:即检验查询的结果是否返回数据,请参见https://javarevisited.blogspot.com/2016/01/sql-exists-example-customers-who-never-ordered.html)中使用SELECT * 要比SELECT 1的速度更快一些。此观点搁在过去可能会有几分道理。但是现在,各种数据库解析器已经发展得相当智能了,它们判断EXISTS语句的效率,与产生SELECT结果列表(请参见https://javarevisited.blogspot.com/2016/04/how-to-convert-result-of-select-command-to-comma-separated-String-in-SQL-Server.html)将毫无关系。

结论

通过上述七点分析,相信您应该明白了为什么不能在SQL查询中滥用SELECT * 的原因吧?可见,您应该尽可能地在查询中,使用显式的列名称,而不是那些星号通配符。此举不但能够提高您的代码效率,也可以使您的程序更加清晰。与此同时,该方法还能够帮助您创建各种具有可维护性的代码。而且,如果后期在表中有新的一列被添加的话,您的代码也不会因此受到影响,您仍然会拥有来自原始数据表的参考视图。

原文标题:7 Reasons Why Using SELECT * FROM TABLE in SQL Query Is a Bad Idea,作者:Javin Paul

【译稿,合作站点转载请注明原文译者和出处为.com】

(责任编辑:人工智能)

推荐内容
  • 戴尔15m7628(一款高性能笔记本电脑,让您轻松应对各种任务)
  • windows 7系统中的用户账户前面的图标显示一个红叉且无法删除
  • windows 7任务栏时间显示个性化设置图文教程
  • 一张PE光盘破解windows 7开机密码步骤
  • Justniffer 是一个可用于替代 Snort 的网络协议分析器。它非常流行,可交互式地跟踪/探测一个网络连接。它能从实时环境中抓取流量,支持 “lipcap” 和 “tcpdump” 文件格式。它可以帮助用户分析一个用 wireshark 难以抓包的复杂网络。尤其是它可以有效的帮助你分析应用层流量,能提取类似图像、脚本、HTML 等 http 内容。Justniffer 有助于理解不同组件之间是如何通信的。功能Justniffer 可以收集一个复杂网络的所有流量而不影响系统性能,这是Justniffer 的一个优势,它还可以保存日志用于之后的分析,Justniffer 其它一些重要功能包括:1.可靠的 TCP 流重建它可以使用主机 Linux 内核的一部分用于记录并重现 TCP 片段和 IP 片段。2.日志保存日志用于之后的分析,并能自定义保存内容和时间。3.可扩展可以通过外部的 python、 perl 和 bash 脚本扩展来从分析报告中获取一些额外的结果。4.性能管理基于连接时间、关闭时间、响应时间或请求时间等提取信息。安装Justniffer 可以通过 PPA 安装:运行下面命令添加库:$ sudo add-apt-repository ppa:oreste-notelli/ppa更新系统:$ sudo apt-get update安装 Justniffer 工具:$ sudo apt-get install justniffermake 的时候失败了,然后我运行下面的命令并尝试重新安装服务$ sudo apt-get -f install示例首先用 -v 选项验证安装的 Justniffer 版本,你需要用超级用户权限来使用这个工具。$ sudo justniffer -V示例输出:1.以类似 apache 的格式导出 eth1 接口流量,显示到终端。$ sudo  justniffer -i eth1示例输出:2.可以用下面的选项跟踪正在运行的tcp 流$ sudo  justniffer -i eth1 -r示例输出:3.获取 web 服务器的响应时长$ sudo justniffer -i eth1 -a  %response.time示例输出:4.使用 Justniffer 读取一个 tcpdump 抓取的文件首先,用 tcpdump 抓取流量。$ sudo tcpdump -w /tmp/file.cap -s0 -i eth0然后用 Justniffer 访问数据$ justniffer -f file.cap示例输出:5.只抓取http 数据$ sudo justniffer -i eth1 -r -p port 80 or port 8080示例输出:6.获取一个指定主机的 http 数据$ justniffer -i eth1 -r -p host 192.168.1.250 and tcp port 80示例输出:7.以更精确的格式抓取数据当你输入 justniffer -h 的时候你可以看到很多用于以更精确的方式获取数据的格式关键字。$ justniffer -h示例输出:让我们用 Justniffer 根据预先定义的参数提取数据。$ justniffer -i eth1 -l %request.timestamp %request.header.host %request.url %response.time示例输出:其中还有很多你可以探索的选项。总结Justniffer 是一个很好的用于网络测试的工具。在我看来对于那些用 Snort 来进行网络探测的用户来说,Justniffer 是一个更简单的工具。它提供了很多 格式关键字 用于按照你的需要精确地提取数据。你可以用.cap 文件格式记录网络信息,之后用于分析监视网络服务性能。
  • windows 7整理磁盘时提示检查不能执行的原因及解决方法