关于SQL中SELECT *(星号)的危害论
2024-09-06 22:07:38
听闻有许多人是禁止开发人员在SQL中使用SELECT *的,这里翻译一下StackOverflow的一篇提问,个人认为相当客观
【SELECT *】危害主要有以下几点:
- 给数据消费者传数据的低效。当你SELECT *后常常你会从数据库查询出比你应用的功能实际需要过多的列,这还可能导致多余数据从数据到服务端到客户端,从而导致机器负担的增加,同样地网络传输也会增加负担。特别当数据表增加了新列,但是功能实现那根本又不需要。
- 索引问题。想象一下这样一个场景:你需要调一个Query调到一定的高性能。如果你用了SELECT *然后返回全部列超过了你需要的列,服务端经常需要为接收你的数据而消耗代价更多的函数而本来是不用的。举个例子,你不可能简简单单创建一个覆盖你SELECT出来全部列的索引,即使你这样做了(包含全部列,想想都可怕),下一个挖坑人又在数据表中增加了新的列就导致你原本已覆盖的索引无法优化了,然后你会惊奇地发现你的Query性能噗噗噗地下降,又没有明显的原因。
- 绑定问题。当你SELECT *之后,有可能查询到来自两张表但是名称一样的列。这样可能会引起数据绑定端或者功能点崩溃,想想返回来有两列数据都是ID,谁TM知道用哪一列?SELECT *还可能搅乱视图(部分数据库、版本)——当底层数据表结构改变,视图又没有新建,视图的数据可能会返回无意义的数据(名称乱不好维护?)。最惨的,你能折腾好以你命名的列,但新来的挖坑人要加入列的时候就不知道他应该如何命名列名才不会与你已经埋好的列名冲突了。
但并不是说【SELECT *】只有坏处,以下用例就可以宽泛地使用:
- 临时查询。当调试东西,特别是某一表自己不熟悉的时,SELECT *就显得很友好了。自己就不用先研究一番这表有啥表明了。这样表的列名越长SELECT *加分就越高。
- 当*表示一行。在下面的用例中SELECT *没啥问题的——之前也有谣传这样写是性能杀手,也许这传说几年前还有点说服力,但是现在不是:
SELECT COUNT(*) FROM table;
在此用例中“*”表示“数一下行数”,如果你用列名替代这表示要数一下列对应值不为NULL的行数。对我来说,COUNT(*)才是本质意义的数行数,这样你也避开了擦边案例(例如聚合搜索中应被消除的NULL值)【译者觉得还是COUNT(Id)或者COUNT(主键)靠谱,这里只是说明数行数的情况,即SELECT * 代表一行时使用没啥毛病】
以下类型的Query也是一样的:SELECT a.ID FROM TableA a
WHERE EXISTS (
SELECT *
FROM TableB b
WHERE b.ID = a.B_ID);在任何合格的数据库中,“*”就是表示“一行”,不管你在子查询中放了啥。一些人用在SELECT中用ID或者数字1,在我看来在这些约定相当的扯淡。你的意思是要“数行数”,“*”就是用来干这个的。做这些查询优化的知道这个的都是智者。(实际上,我只知道SQL Server和Oracle就是这样的)
最新文章
- Datazen图表创建和发布
- 利用ARCHPR明文破解获取PDF
- Python之调用函数
- 从零开始学习Node.js例子六 EventEmitter发送和接收事件
- C++学习基础九——继承
- 常用的mysql操作命令
- C#获取本周周一的日期
- 小心!#define max(a,b) a>;b?a:b
- gradle使用国内源
- java初学的几个问题
- XML数据的读取—数据库配置文件
- fiddler还是浏览器的问题
- jsp中使用java函数
- mog使用指南
- Image和字节数组互转
- linux下磁盘存储空间不足
- js导航栏单击事件背景颜色变换
- json转换导致金额失真问题解决
- nltk分词
- Ubuntu 16——安装——ns2.35和nam
热门文章
- 【Spring Boot】内嵌容器
- Java中的long类型和Long类型比较大小
- R语言中查询帮助
- centos 7 U盘 uefi 模式装机
- MongoDB笔记: 分片集群
- win10安装grafana
- Python80个练手项目列表
- EV录屏 --- 免费无水印,集视频录制与直播功能于一身的桌面录屏软件, 支持录屏涂鸦、实时按键显示、视频体积压缩等实用功能
- 【jmeter】使用jmeter进行测试-示例
- git解决error: The following untracked working tree files would be overwritten by checkout