在使用同样索引,同样需要回表查询的情况下,应该使用
我能想到的使用后者的优点可能就是节省那么一点点带宽,
缺点是极大的影响开发效率和维护难度,并且 mapper 文件难看,难懂
1
chenset 2020-08-04 11:14:38 +08:00
1.特别需要注意性能与并发或者大 text 字段的时候就列出字段
2.其他情况直接* 两者不误 |
2
clf 2020-08-04 11:18:42 +08:00
现在大部分 select 操作应该都是 orm 框架帮我们处理了?
对于少数的自己写的查询,我一般都是 select 字段,字段,字段 这样对应自己定义的对象来处理。(反正都是用 navicat 的查询构造器来写的,勾选一下参数的事情,不需要特别麻烦。 |
4
lux182 OP @lychs1998 我感觉最近几年项目用 orm 反而少了。用工具构造查询是挺方便,缺点就是每次修改数据库就要在代码里 review 一遍。而且字段列举很多让人看的不舒服
|
5
piecehealth 2020-08-04 11:23:06 +08:00
遇到过一次玄幻的事,用的 PostgreSQL 9+,select 字段...(字段不全是索引列) 跟 select * 用的索引不一样( pg 没法指定索引),select * 用的是效率高的索引。
|
6
cruii 2020-08-04 11:24:27 +08:00
我觉得把字段写清楚更好看,能让别人清楚的知道,你想拿哪些数据。
|
7
CrazyEight 2020-08-04 11:24:53 +08:00
select *用不到索引覆盖,而且字段过多会占用更多的 joinBuffer 会导致表连接变慢
|
8
lux182 OP @piecehealth select * 会有索引优化器选择合适的索引吧?
|
9
lux182 OP @cruii 当字段只有 3 、5 个时候比较清楚,当字段 10 多个以上时候,我觉得不如我直接看 model,还有注释呢
|
10
lux182 OP @CrazyEight 已经说明了不考虑覆盖索引,实际情况覆盖索引使用的字段也很少,基本不超过 3 个。joinBuffer 这个触及知识盲点
|
11
Vegetable 2020-08-04 11:36:14 +08:00
不推荐 select * ,不是因为性能问题,而是你没法控制 * 代表了什么,你的代码有可能会依赖数据库结构而不自知。
|
13
xuanbg 2020-08-04 11:41:12 +08:00
一般都是*,特殊情况列出字段
|
14
InkAndBanner 2020-08-04 11:43:31 +08:00
还是写清楚更好 用啥拿啥
|
15
lux182 OP @xuanbg 我也是这样用的。接触的传统型公司反而是列出字段的居多,比如恒生,他们会用工具生成一系列 mapper,service,里面各种条件表达式。说实话还不如自己写
|
16
stabc 2020-08-04 11:48:03 +08:00
我一般是排除比较大的字段,但是 SQL 语句目前没法简单的排除字段
|
17
ragnaroks 2020-08-04 11:48:48 +08:00
手动查询用"*",代码里面指定字段,因为有自动步枪
|
18
yuanbo6 2020-08-04 11:49:34 +08:00
前一阵看了一个文章说还是推荐带字段,原因太长我给忘了……
|
19
yc8332 2020-08-04 11:49:47 +08:00
这个要看吧。。如果没差几个字段,又不是大字段。。无所谓
|
20
superrichman 2020-08-04 11:50:05 +08:00 via iPhone
在我这里你敢用 select *会被打死的 /doge
|
21
meeop 2020-08-04 11:50:12 +08:00
我的原则是在性能不是问题时注重开发效率,性能有问题在考虑优化
绝大多数场景性能都不是问题,所以放心用 select * 除非是有 orm 帮你生成 |
22
baiduyixia 2020-08-04 12:06:08 +08:00 1
|
23
Jackeriss 2020-08-04 12:45:10 +08:00 via iPhone
*能不用就不用,就像 import *一样,谁知道你的*里有什么?
|
24
Jooooooooo 2020-08-04 12:57:33 +08:00
如果是真的要捞出全部字段就用
数据库对 * 有专门的优化 |
25
vindac 2020-08-04 13:22:30 +08:00
额,我们又上百个字段的表从其中取五六十个,都是 select *
|
26
lolizeppelin 2020-08-04 13:39:01 +08:00
不说其他的 一旦你数据库表字段有增加,所有对这个表 select*的代码部分都要改
如果只是写点小东西, 无所谓 |
27
lux182 OP @superrichman 所以啊,你的原因是?
|
28
VictorJing94 2020-08-04 13:46:14 +08:00
不应该,虽然我经常用,数据库栏位变动会导致*到的数据不可控
|
29
lux182 OP @lolizeppelin 字段增加,增加 model 字段不就可以吗?
|
30
lux182 OP @VictorJing94 这里可控是为了什么?作为底层 service 在对外暴漏的时候还有一层转换的啊
|
31
lolizeppelin 2020-08-04 13:58:32 +08:00
|
32
lolizeppelin 2020-08-04 14:03:18 +08:00
@lux182
如果你只想抬杠,或者就是要说 select*好,那么你赢了 如果不是,我建议你多看看大型项目,好好理解下那些看上去多余的做法 很多做法在小项目里是不需要的,大型项目周期长迭代多,很多看上去东西都是为了解决版本迭代更新兼容 你随手写点东西,压根就不用考虑迭代更新兼容,甚至不用考虑单元测试 自然很多做法就是多余的,禁止 select*就是基础中的基础 |
33
wuketidai 2020-08-04 14:05:18 +08:00
显示优于隐式
|
34
brader 2020-08-04 14:06:18 +08:00
@lux182 字段增加,增加 model 字段不就可以吗?
我想你对这里有个狭隘的误会,不同语言中,是有不同表现的,对于一些语言,数据库增加字段,是不需要去代码的 model 增加字段的。 |
35
admol 2020-08-04 14:14:38 +08:00 4
想象一个场景, 你有一个接口, 每秒有非常多用户的来请求, 你后面的逻辑涉及到数据库语句写的是 select * ; 平时这可能没有任何问题, 但是有一天产品需求发生变化, 你的数据库需要添加一个字段, 并且这个字段需要返回, 请问你应该怎样来开发这个功能并上线?
先上数据库 DML 语句还是先上你的代码? 如果先上数据库, 你线上代码还是老的, 还没有那个新的字段, 代码全是 select * , 而你与之对应的 model 肯定是没有这个字段, 如何与它映射? 是否会报错? java 的 mybatis 至少会. 如果先上代码, 加入你有 10 台服务器呢, 代码上线, 请求进来之后全是找不到新字段. 如果之前你这个表涉及的 SQL 语句全部都是指定字段 select c1,c2,c3 from table , 那你就可以放心大胆的先让 DBA 给你添加表字段, 然后慢慢上线你的服务, 这部分至少不会有什么问题 |
36
hello826 2020-08-04 14:14:54 +08:00
那为啥阿里的 java 开发手册,第五章 Mysql 数据库,第三小节 sql 语句
[强制] 不要使用 count(列名)或 count(常量)来替代 count(*),count(*)是 SQL92 定义的标 准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。 这个 mysql 实战也是推荐使用 count(*) |
37
hello826 2020-08-04 14:15:18 +08:00
|
38
dddd1919 2020-08-04 14:17:14 +08:00
如果需要所有字段,区别不大。
如果只需要部分列的话最好显示声明要返回的字段,省带宽性能更好使用稳定。 显示声明字段还有个好处就是如果字段全部在索引中,可以直接从索引返回结果 |
39
wangritian 2020-08-04 14:22:29 +08:00
开发时间特别紧用*,否则好好写
|
40
MeteorCat 2020-08-04 14:26:09 +08:00 via Android
大表筛选不要用,小表筛选可以用;开发阶段尽量用*,正式验收尽量不要用*;
有时候项目需求文档很多版本,这样加个*直接获取比较方便 |
42
gz911122 2020-08-04 14:33:32 +08:00
@lolizeppelin 跟顺序有什么关系啊?
|
43
lux182 OP |
44
lux182 OP @lolizeppelin
”新字段不在最后一行的时候,你 model 全乱“ ,这点我一直没遇到过,你的场景是什么啊,用的什么框架? ”遇到需要热更需要先升级数据库,再慢慢升级程序的时候,你 select*咋搞” ,这种情况也是比较常见的,我们也经常先更新数据库,后上程序的。所以还是不知道你的场景。 所以你说的这几点没有说服力。 |
45
lux182 OP @brader 不是语言的问题,而是框架设计问题。我看过一些 python 程序员喜欢直接拿数据库 map 结果返回前端
|
46
lux182 OP @admol “如果先上数据库, 你线上代码还是老的, 还没有那个新的字段, 代码全是 select * , 而你与之对应的 model 肯定是没有这个字段, 如何与它映射? 是否会报错? java 的 mybatis 至少会.”
我使用过程中,这种情形很多,mybatis 不会报错的 |
47
lolizeppelin 2020-08-04 15:11:09 +08:00
|
48
wakzz 2020-08-04 15:18:19 +08:00
单单考虑业务的问题,也不建议用 select *,因为一旦业务变更数据库新增字段,就会导致线上程序 sql 映射错误,不好向前兼容。
|
50
VictorJing94 2020-08-04 17:03:00 +08:00
@lux182 楼下说清楚了.......应该不需要我再重复了吧
|
51
useben 2020-08-04 17:07:27 +08:00
看查询的索引类型, 不同不同处理
|
52
wangbudong 2020-08-04 19:09:18 +08:00
没有性能问题的情况下,也就是不会导致 io 阻塞的情况都可以用 select * ,至于说啥迭代,数据库和 entity 的关系处理好了,只需要改 entity 和数据库,不用 orm 也可以
|
53
1069401249 2020-08-04 19:20:34 +08:00
谁用 select *我直接打死,占 io 内存,大列表的时候 select*有几次导致内存爆掉了
|
54
akira 2020-08-04 19:52:24 +08:00
小项目随便你怎么写都行。 稍微有点量的项目 还是别用 select *了,回头逐个地方修改还是挺麻烦的
|
55
realpg 2020-08-04 21:07:15 +08:00
结合实际,没有一杆子打死。
性能,吞吐,负载综合考虑。 |
56
CEBBCAT 2020-08-04 21:08:57 +08:00 via Android
谢邀,Golang 选手,SQL 手写
|
57
DelayNoMay 2020-08-04 21:11:03 +08:00
用 * 的话,数据库新增一个字段就报 scan error 了
|
58
blockmin 2020-08-04 21:16:17 +08:00
测试的时候数据都是几亿条,用 select * 的话下游团队会砍死我们的
|
59
crclz 2020-08-04 21:40:09 +08:00
事务类的操作,用 ORM,例如 SpringDataJpa 的 repository
查询类的操作,用 select*,外加 ModelMapper ( java )或者 AutoMapper ( c#)之类的工具. 对于大字段,请将表拆分。 |
60
woshipanghu 2020-08-04 21:55:59 +08:00
说实话 你写的严谨一点那是不用*
实际开发的时候用*没什么问题 不要有敏感字段暴露出去就行 大部分项目不会因为加了*或没加*产生太大的影响 读写多的几张表自然会想着去优化 |
61
CrazyMoon 2020-08-04 21:57:59 +08:00
这要看相关代码的动态能力。
另外如果是列数据库,基本不能用它。 |
62
stevenkang 2020-08-04 22:08:47 +08:00
个人项目:select * —— 毕竟增减字段方便,自己的需求自己明白,只要快就行。
公司项目:select 字段 —— 毕竟产品不来需求,字段绝笔不会去改,改起来费时间慢点就慢点,只要稳就行。 |
63
tairan2006 2020-08-04 22:20:55 +08:00
单表查询一般都是 orm,join 的时候你跟我说你用 select *?
不过做动态 sql 的时候只能用*,因为连表名都是动态传进来的。 |
64
chihiro2014 2020-08-05 02:00:15 +08:00
其实可以去看看 CMU 数据库系统这块的 SQL 优化和索引部分
https://www.bilibili.com/video/av85655193 |
65
saberlong 2020-08-05 08:40:58 +08:00 via Android
代码上没碰到问题是因为用 orm 之类有映射功能的。原始的方式是和查询列顺序有关的。直接写*会导致这部分业务逻辑错误。写明列则只需修改需要增加列的地方。一个人了解所有项目是不可能的,允许随意使用*。那么发布时,可能就碰到惊喜。
|
66
hxy91819 2020-08-05 09:03:00 +08:00
在关注性能的业务场景下,任何情况都严禁使用。
|
67
lux182 OP @1069401249 上面还有一个也这样说,"把 xxx 打死",我想你是做领导做久了吧。
|
68
okjb 2020-08-05 12:00:23 +08:00 via Android
跟使用场景有关。我自己私人查数据爱用检索全部字段。业务场景就检索特定字段。又说了一堆废话
|
69
no1xsyzy 2020-08-05 12:48:55 +08:00
@tairan2006 #63 join 也可以 select a.*, b.* 来着
如果有重名不记得是报错还是自动重命名了 |
70
no1xsyzy 2020-08-05 13:12:01 +08:00
@lolizeppelin #31 你 model 不读字段名的吗?
稍微瞄了眼 SQL92 没看到哪指明 <select list> 的顺序在结果中必须被保持。 |
71
wolong 2020-08-05 23:50:27 +08:00
先 select *一把梭,后期出现性能问题了再优化成 select 字段 1, 字段 2
|
72
tairan2006 2020-08-06 09:23:11 +08:00
@no1xsyzy mysql 会报错,有歧义
|