很多程序员视 SQL 为洪水猛兽。SQL 是一种为数不多的声明性语言,它的运行方式完全不同于我们所熟知的命令行语言、面向对象的程序语言、甚至是函数语言(尽管有些人认为 SQL 语言也是一种函数式语言)。
我们每天都在写 SQL 相关的语句用于各种数据索引中。关于SQL 优化的那些事儿,鲜少有人能总结全面。今天,就SQL优化那些事儿,我们准备了四个问题让网友就此展开讨论:
1.您一般在写SQL时需要注意哪些问题,可以提高查询的效率?
2.请分享一次印象深刻的SQL优化:除了SQL改写,还要考虑什么?
3.如何查看到效率低的SQL?
4.请简要总结下,您的SQL语句优化技巧(至少写3点)
接下来,我们就来看看有哪些精彩回答吧!
@lxl489591374
1、您一般在写SQL时需要注意哪些问题,可以提高查询的效率?
a) 索引(组合索引):限制条件、连接条件是否有索引;能不能使用到索引
b) 数据量大小:是否要分页,排序
c) 绑定变量: 大多数情况绑定变量能提高查询效率,但也有降低效率的情况
d) 尽量不要用select *,不需要的字段尽量少查,多查的字段可能有行迁移/行链接(timesten还有行外存储问题),或是lob类型的,增加io
e) 批量和并行
2、请分享一次印象深刻的SQL优化:除了SQL改写,还要考虑什么?
缓存:查询特别频繁的结果是否可以缓存,比如oracle的/*+ result_cache */
索引:sql中的条件,可能没有按希望的那样使用索引
3、如何查看到效率低的SQL?
a) 定位低效sql:各种性能报告awr addm ash;性能视图;监控工具查看监控实时session,用这些手段找到可能有问题的sql
b) 分析执行计划:重点检查驱动表与被驱动表顺序、表连接算法、排序是否有索引、索引使用
4、请简要总结下,您的SQL语句优化技巧(至少写3点)
a) 索引: 排序字段有正确的索引,驱动表的限制条件有索引,被驱动表的连接条件有索引
b) rownum固定执行计划,hint固定执行计划
c) 避免隐式转换
d) union尽量写成union all
e) 左右连接尽量少写
@lastwinner
1、您一般在写SQL时需要注意哪些问题,可以提高查询的效率?
A:业务理解正确+实现逻辑正确+减少重复计算+只取需要的列+尽量避免函数调用+合理使用分析函数
2、请分享一次印象深刻的SQL优化:除了SQL改写,还要考虑什么?
A:设计的不合理、业务需求的不合理、问题SQL并非根本原因
3、如何查看到效率低的SQL?
自动:AWR+ASH+ADDM
手动——
当前的:v$SQL+v$Session
历史的:DBA_HIST_SQLSTAT+DBA_HIST_SNAPSHOT
4、请简要总结下,您的SQL语句优化技巧(至少写3点)
1)避免不使用绑定变量
2)等价改写(with等)
3)固定执行计划
4)收集/设定统计信息
5)创建/更改索引
6)消除表的高水位
@fantigcy
1、您一般在写SQL时需要注意哪些问题,可以提高查询的效率?
(1)考虑表没有索引或者没有用到索引,尽量使用索引,索引很多情况下可以提高查询效率
(2)避免使用or语句
(3)查询出的数据量过大(可以采用多次子查询,其他的方法降低数据量)
(4)应尽量避免在 where 子句中对字段进行表达式操作
2、请分享一次印象深刻的SQL优化:除了SQL改写,还要考虑什么?
将left join语句改写成标量子查询,效率明显提高
除了SQL改写,仔细分析sql需求
3、如何查看到效率低的SQL
查看慢查询日志(slow_log)
查看执行计划(explain)
4、请简要总结下,您的SQL语句优化技巧(至少写3点)
(1)应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
(2)很多时候用 exists和not exists代替in和not in语句是一个好的选择
(3)任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
@xuexiaogang
1、您一般在写SQL时需要注意哪些问题,可以提高查询的效率?
首先根据需求是不是要写SQL实现。如果不用写就可以实现,那么就不写。
其次,看看这个表有多大,如果就是几百条数据,就没有所谓效率之分。怎么写效率都不低。再次如果适合大表。首先要避免全表扫描,选择合适的谓词进行过滤。然后查看SQL的执行计划是不是最优,然后结合统计信息看看执行计划是不是对。
都没有问题了,那么就是一个合格的SQL,自然效率得到了保障。
2、请分享一次印象深刻的SQL优化:除了SQL改写,还要考虑什么?
影响深刻的很多,都涉及改写。但是不全部是改写。有一次发现数据循环实在花了很多时间。而循环是根据实际一天天,从最早到现在来做的。那么理论上上线一年多的系统也就循环几百次就够了。为什么执行时间超长?不由得想到看看最开始的时间究竟是多少。一看吓一跳,是1900年,第二次鸦片战争八国联军打进北京的时候。明显这个数据质量有问题,没有做校验。我们系统是不可能出现跨几个世纪的。所以这个就是循环次数多的原因。上百年的一天天循环,能不长吗?所以我们在改写之余,也要重视一下数据质量。因为如果逻辑没有问题,那么必然是其他的因素导致了异常。
3、如何查看到效率低的SQL?
方法很多。Oracle有AWR 和EM中性能监控的捕获5s以上的。MySQL有慢查询日志。这些都是低效的SQL,因为低效的必然是执行时间超过了预定标准的。1毫秒的基本都是高效的。越快越高效,越慢越低效。
4、请简要总结下,您的SQL语句优化技巧(至少写3点)
(1)对查询进行优化,应尽量避免全表扫描,SQL应该包含符合客观情况的where条件;
(2)应尽量避免在 where 子句中使用!=或<>操作符;
(3)不要使用 not in;
(4)绝对禁止通配符第一位是%;
(5) 禁止在where 子句中的“=”左边进行函数、算术运算或其他表达式运算;
(6)循环嵌套不得超过3层;
(7)避免不必要和无意义的排序;
(8)尽可能减少关联表的数量,关联表不要超过3张;
(9)where条件一定要包含索引的第一列