为什么不要用select *

本文探讨了在数据库查询中使用SELECT *指令的潜在问题,包括程序变更隐患和性能影响。指出这种做法可能导致不可预知的问题,并从多个角度分析其弊端。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很可能这会是一个面试题

主要从以下几个角度:
1. 程序变更问题,出现不可以预知隐患;
假设某一天修改了表结构,如果用select *,返回的数据必然会会变化,客户端是否对数据库变化作适配,是否所有地方都做了适配,这都是问题。

2. 性能问题
a. 使用了select ,必然导致数据库需要先解析代表哪写字段,从数据字段中将*转化为具体的字段含义,存在性能开销;
b. 不可能对所有字段建索引,在索引优化必然会有局限性,导致查询时性能差;
c. 可能会存在不需要的列,传输过程中有不必要的性能损耗;
d. 客户端解析查询结果也需要更多损耗;

所以select *不存在对应用实际的任何好处,不但影响性能,而且应用变更中都是坑。

<think>好的,用户之前让我扮演面试官,评价他对synchronized和Lock锁区别的回答,并给出了详细的优化建议。现在用户又提出了一个新的面试问题,关于慢SQL的优化,他回答了两点:避免使用select *和避免嵌套子查询。我需要评估他的回答,指出不足之处,并给出优化建议。 首先,用户提到的两点确实是常见的优化方法,但显然不够全面。我需要思考还有哪些关键点他没有提到。比如索引的使用、执行计划分析、表结构设计、分库分表、连接池配置等等。另外,他的回答比较简略,可能需要更详细的解释和例子。 接下来,我需要考虑用户可能的背景。他可能在准备面试,想了解如何更好地回答技术问题。因此,我的回答需要结构清晰,层次分明,帮助他补充遗漏的知识点,同时指出他的回答中的误区或不足。 用户可能没有意识到,除了避免select *和子查询,还有更多优化手段。比如,索引的合理使用,避免索引失效的情况,使用JOIN替代子查询,分页优化,数据库参数调优,读写分离,硬件升级等。此外,分析慢SQL的方法,如使用EXPLAIN命令,也是重要的步骤。 另外,用户提到的嵌套子查询可能需要更准确的表述。有时候子查询是必要的,但可以通过其他方式优化,比如转换为JOIN操作。需要指出在哪些情况下子查询会影响性能,以及替代方案。 还需要考虑用户回答的结构是否完整。比如,是否有分析慢SQL的原因,优化步骤,工具使用等。这些方面都是面试中常被问到的,需要补充进去。 最后,要确保建议具体、有例子,并且条理清晰,便于用户理解和记忆。可能还需要指出他回答中的误区,比如是否所有子查询都需要避免,或者select *是否总是低效的,是否有例外情况。</think>你的回答方向正确但存在关键遗漏和表述不精确之处,以下是分层优化建议: --- ### 一、需纠正的误区 1. **嵌套子查询的表述** × 原表述:"避免嵌套内查询" √ 精确表述:**应优先使用JOIN替代相关子查询**(特别是WHERE中的子查询),但部分场景(如统计聚合)可保留 2. **select *的问题本质** × 原表述:"尽量不要select *" √ 深层原因: - 导致回表查询(若未覆盖索引) - 增加网络传输量 - 破坏覆盖索引优化机会 - 增加内存消耗(如text/blob字段) --- ### 二、必须补充的核心优化点 1. **索引优化(最重要)** ```sql -- 错误案例:未命中索引 SELECT * FROM orders WHERE DATE(create_time) = '2023-10-01'; -- 优化方案:使用范围查询 SELECT * FROM orders WHERE create_time BETWEEN '2023-10-01 00:00:00' AND '2023-10-01 23:59:59'; ``` - 避免索引失效:函数操作、隐式类型转换、前导通配符 - 联合索引的最左匹配原则 2. **执行计划分析** ```sql EXPLAIN SELECT ... -- 重点关注type列(ALL->全表扫描)和Extra列(Using filesort/Using temporary) ``` - 关键指标:rows(扫描行数)、filtered(过滤比例) 3. **分页优化** ```sql -- 传统分页(深度分页性能差) SELECT * FROM table LIMIT 1000000, 20; -- 优化方案(延迟关联) SELECT * FROM table t1 JOIN (SELECT id FROM table LIMIT 1000000, 20) t2 ON t1.id = t2.id; ``` --- ### 三、优化层级框架建议(结构化回答) | 优化层级 | 具体措施 | |----------------|--------------------------------------------------------------------------| | **SQL语句层** | 避免SELECT * / 用JOIN替代子查询 / 拆分复杂SQL / 预处理语句防注入 | | **索引层** | 覆盖索引设计 / 避免冗余索引 / 使用索引下推 / 定期analyze table更新统计信息 | | **架构层** | 读写分离 / 分库分表(如按时间分片) / 引入缓存(Redis) | | **数据库配置** | 调整innodb_buffer_pool_size / 优化连接池参数 / 合理设置事务隔离级别 | --- ### 四、典型错误场景补充 1. **隐式类型转换** ```sql -- user_id是varchar类型时(导致索引失效) SELECT * FROM users WHERE user_id = 12345; ``` 2. **错误排序方式** ```sql -- 混合ASC/DESC导致filesort SELECT * FROM orders ORDER BY create_time ASC, update_time DESC; ``` --- ### 五、建议回答结构示例 "慢SQL优化需要系统性分析: 1. **定位问题**:通过慢查询日志找到目标SQL,用EXPLAIN分析执行计划 2. **语句优化**:避免SELECT *,用JOIN优化子查询,注意分页深度问题 3. **索引设计**:确保查询命中索引,注意联合索引顺序,定期维护索引统计信息 4. **架构优化**:对千万级数据考虑分库分表,高频读操作使用缓存 5. **参数调优**:根据业务特点调整数据库连接池和缓冲池配置" --- ### 六、需要强调的进阶技巧 1. **冷热数据分离**:将历史数据归档到历史表 2. **异步处理**:将统计类查询转为离线计算 3. **执行计划固化**:使用MySQL的optimizer hints强制索引 ```sql SELECT /*+ INDEX(orders idx_create_time) */ * FROM orders WHERE create_time > '2023-01-01'; ``` 这种分层表述能体现系统化思维,比单纯罗列技巧更有技术深度。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值