sql优化经验干货分享

好的sql可以提高接口效率,差的sql会拖慢整个服务,sql优化是开发过程中少不了要面对的问题。

一、如何判断你写的sql是否是个好sql

1)explain命令

explain select * from product where name = 'ps4';

expain出来的信息有10列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra,可以根据返回的信息选择添加、修改索引,或者修改查询方式

id: SELECT 查询的标识符

select_type: SELECT 查询的类型.

table: 查询的是哪个表

partitions: 匹配的分区

type: join 类型

possible_keys: 此次查询中可能选用的索引

key: 此次查询中确切使用到的索引

ref: 哪个字段或常数与 key 一起被使用

rows: 显示此查询一共扫描了多少行(估计值)

filtered: 表示此查询条件所过滤的数据的百分比

extra: 额外的信息
2)监控

druid支持慢查询监控

spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.slow-sql-millis=100

Hikari可以使用P6Spy添加监控

spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
spring.datasource.url=jdbc:p6spy:mysql://localhost:3306/product?useUnicode=true&characterEncoding=utf-8&useSSL=true&autoReconnect=true&serverTimezone=UTC

配置文件

module.log=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=org.pkaq.core.log.P6SpyLogger
# 使用日志系统记录sql
appender=com.p6spy.engine.spy.appender.Slf4JLogger
## 配置记录Log例外
excludecategories=info,debug,result,batc,resultset
# 设置使用p6spy driver来做代理
deregisterdrivers=true
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动 
driverlist=com.mysql.jdbc.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 秒
outagedetectioninterval=2

二、如何优化sql

1)优化工具SQLAdvisor

SQLAdvisor是由美团点评公司技术工程部DBA团队开发维护的一个分析SQL给出索引优化建议的工具。它基于MySQL原生态词法解析,结合分析SQL中的where条件、聚合条件、多表Join关系 给出索引优化建议。

地址:https://github.com/Meituan-Dianping/SQLAdvisor

2)优化索引

1.索引并不是越多越好,索引越多,在增删改的时候性能越低。虽然提升了查询性能,但是会降低写数据的性能,同时会增加系统负载。如果是在是需要提高查询效率,建议增加冗余表专供查询。(通过同步binlog,专门独立出一张表,或者数据定时采集到hive,通过hive分析)

2.选择正确的索引类型

3.合理使用复合索引,根据最左原则,为复合索引选择正确的列顺序。

4.为分区表选择正确的索引类型

5.不要给区分度不大的字段建立索引,比如性别这种

6.包含在ORDER BY、GROUP BY、DISTINCT中的字段建议使用索引

3)优化sql

1.写比较复杂的sql时,建议先使用执行下explain命令,避免全表扫描

2.避免在 where 子句中对字段进行 null 值判断,否则会全表扫描,建议不要给字段默认值设置为null

3.不要在where 中使用!=或<>,否则会全表扫描

4.用EXISTS替代IN、用NOT EXISTS替代NOT IN(EXISTS:是否存在符合子查询中指定条件的行,效率高)

5.使用union代替or

6.慎用like,'abc%'这种会使用索引,其他都不会使用

7.应尽量避免在 where 子句中对字段进行表达式操作和函数操作,会进行全表扫描

8.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引

9.尽量使用数字型字段,否则会降低查询和连接的性能,同时会增加存储开销

10.尽可能的使用 varchar代替 char ,可以节省存储空间得同时,查询在一个相对较小的字段内搜索效率要高

11.避免使用select * ,用具体字段代替

12.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)

13.避免一次查询过多

发布了43 篇原创文章 · 获赞 0 · 访问量 3908

猜你喜欢

转载自blog.csdn.net/zhangdx001/article/details/105047116