mysql sql 优化

  1. 使用索引:为常查询的列添加索引可以显著提高查询速度。
CREATE INDEX idx_column ON table_name(column_name);
  1. 查询时只查询用到的字段,避免select *
SELECT id, name FROM table_name;
  1. 使用LIMIT限制查询结果集大小:
SELECT id, name FROM table_name LIMIT 10;
  1. 确保GROUP BY和ORDER BY中的列有合适的索引。
  2. 使用EXPLAIN分析查询计划,调整索引和查询语句。
EXPLAIN SELECT * FROM table_name WHERE column_name = 'value';
  1. 定期优化和重建索引:【特别是发生过大批量delete数据的表,通过优化可以释放回收碎片】
    OPTIMIZE TABLE table_name;
    配合:重新收集下表的统计信息
    analyze table table_name;

  2. 尽量少使用数据区分度不大的索引字段作为查询条件,如类型只有 1种值,当数据量大的时候会严重降低查询效率
    如 where userid=‘123’ and busType=‘view’ userid和view都有索引,当数据量大时busType 只有view这一个值即加不加该条件结果不变,则and busType=‘view’ 会严重降低SQL的查询效率,直接删掉该查询条件即可

  3. SQL时where 条件中的字段不要转换表字段数据类型 如time int char ,避免隐式转化 导致索引失效【无法走索引】

  4. 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算:
    应尽量避免在 where 子句中对字段进行表达式操作
    select id from t where num/2=100
    应改为:
    select id from t where num=100*2
    应尽量避免在where子句中对字段进行函数操作 【特别需要注意:日期】
    select id from t where substring(name,1,3)=‘abc’–name以abc开头的id
    select id from t where datediff(day,createdate,‘2005-11-30’)=0–'2005-11-30’生成的id
    应改为:
    select id from t where name like ‘abc%’
    select id from t where createdate>=‘2005-11-30’ and createdate<‘2005-12-1’

  5. 用union all代替union【数据会去重】

  6. 小表驱动大表: (大数据量)In(小数据量),(小数据量)exits(大数据量)
    优先执行in里面的语句,exists 拿左边的结果匹配exists()中的数据

  7. 循环插入改为批量插入,建议每批数据尽量控制在500以内。如果数据多于500,则分多批次处理。

  8. 判断记录是否存在,不再使用count(*)

SELECT 1 FROM table WHERE a = 1 AND b = 2 LIMIT 1
Integer exist = xxDao.existXxxxByXxx(params);
if ( exist != NULL ) {
  //当存在时,执行这里的代码
} else {
  //当不存在时,执行这里的代码
}
  1. in中值太多
    如果ids超过500条记录,可以分批用多线程去查询数据。每批只查500条记录,最后把查询到的数据汇总到一起返回。

  2. 能用inner join的地方,尽量少用left join
    left join:求两个表的交集外加左表剩下的数据。
    inner join:求两个表交集的数据。
    如果两张表使用inner join关联,mysql会自动选择两张表中的小表,去驱动大表,所以性能上不会有太大的问题。
    如果两张表使用left join关联,mysql会默认用left join关键字左边的表,去驱动它右边的表。如果左边的表数据很多时,就会出现性能问题。
    要特别注意的是在用left join关联查询时,左边要用小表,右边可以用大表。如果能用inner join的地方,尽量少用left join。

  3. 控制索引的数量
    单表的索引数量应该尽量控制在5个以内,并且单个索引中的字段数不超过5个。
    能够建联合索引,就别建单个索引,可以删除无用的单个索引。
    将部分查询功能迁移到其他类型的数据库中,比如:Elastic Seach、HBase等,在业务表中只需要建几个关键索引即可

  4. 选择合理的字段类型
    能用数字类型,就不用字符串,因为字符的处理往往比数字要慢。
    尽可能使用小的类型,比如:用bit存布尔值,用tinyint存枚举值等。
    长度固定的字符串字段,用char类型。
    长度可变的字符串字段,用varchar类型。
    金额字段用decimal,避免精度丢失问题。

  5. sql语句在做一些耗时的操作之前,应尽可能缩小数据范围,这样能提升sql整体的性能

  6. 应尽量避免在 where 子句中使用!=或<>操作符,根据值对应数据量的不同会导致索引失效
    如del_flag有索引,数据del_flag都是为0的记录,当where del_flag !=‘1’ 时就回导致索引失效,从而全表扫描

  7. 应尽量避免在 where 子句中对字段进行 null 值判断,有可能会导致索引失效【对应值数据量改变而改变】
    select id from t where num is null
    可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
    select id from t where num=0

t.create_time is not null 不走索引 【create_time 有索引 只有几条为空null】
20. 未命中索引的情况要具体情况具体分析
随着对应值数据量增加,也会导致未命中索引的情况
21. 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
22. 避免全like
select id from t where name like ‘%abc%’
23.
24.
25.
26.
27.

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值