MySQL优化对于提升数据库查询效率非常的重要,本篇全面总结MySQL优化的9大方法@mikechen。
1.尽量避免在字段开头模糊查询
SELECT * FROM user WHERE name LIKE '%陈%'
会导致数据库引擎放弃索引进行全表扫描,查询效率非常低。
2.避免select *
SELECT * FROM user
将需要查找的字段列出来即可, 比如:
SELECT name, phone,city FROM user
3.in 和 not in 也要慎用
SELECT * FROM t WHERE id IN (1,2,,3)
会导致引擎走全表扫描,对于连续的数值,能用 between 就不要用 in 了。
select id from t where num between 1 and 3
4.尽量避免进行null值的判断
SELECT * FROM t WHERE score IS NULL
将导致引擎放弃使用索引而进行全表扫描。
可以在score 上设置默认值0,确保表中score 列没有null值,然后这样查询:
SELECT id FROM score WHERE score =0
5.查询条件不能用 <> 或者 !=
应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
6.使用连接(JOIN)来代替子查询
例如:我们要将客户基本信息表中没有任何订单的客户删除掉,就可以利用子查询先从销售信息表中将所有发出订单的客户id取出来,然后将结果传递给主查询。
如下代码所示:
DELETE FROM customerinfo WHERE CustomerId NOT IN (SELECT customerid FROM salesinfo);
如果使用连接(JOIN)来完成这个工作,速度将会快很多:
SELECT * FROM customerinfo LEFT JOIN salesinfo ON customerinfo.customerid = salesinfo.customerid WHERE salesinfo.customerid IS NULL;
因为MySQL不需要在内存中创建临时表来完成这个逻辑上需要两个步骤的查询工作。
7.避免大事务
拆分复杂SQL为多个小SQL,可以减少大事务。
8.分段分页进行查询
SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY ID ASC) AS rowid,* FROM infoTab)t WHERE t.rowid > 100000 AND t.rowid <= 100050
查询数据量大的表 会造成查询缓慢,主要的原因是扫描行数过多,这个时候可以通过程序分段分页进行查询,将结果合并处理进行展示。
9.尽量避免向客户端返回大数据量
若数据量过大,应该考虑相应需求是否合理,大数据量的查询,优先使用分页查询。
select * from t where thread_id = 10000 and deleted = 0 order by gmt_create asc limit 0, 15;
仍不能满足需求的,考虑使用es 或者 分库分表。
垂直拆分
垂直拆分又可以分为:垂直拆表和垂直拆库。
1)垂直拆表
即大表拆小表,将一张表中数据不同”字段“分拆到多张表中,比如商品库将商品基本信息、商品库存、卖家信息等分拆到不同库表中。
2)垂直拆库
垂直拆库则在垂直拆表的基础上,将一个系统中的不同业务场景进行拆分,比如把一个数据库拆分为:商品数据库、用户数据库、交易数据库。
如下图所示:
2.水平拆分
前边说了垂直切分还是会存在单库、表数据量过大的问题,当我们的应用已经无法在细粒度的垂直切分时, 依旧存在单库读写、存储性能瓶颈,这时就要配合水平切分一起了,水平切分能大幅提升数据库性能。
这里的水平拆分又可以分为:水平拆表和水平拆库。
1)水平拆表
将数据按照某种维度拆分为多张表,但是由于多张表还是从属于一个库,其降低锁粒度,一定程度提升查询性能,但是仍然会有 IO 性能瓶颈。
2)水平拆库
将数据按照某种维度分拆到多个库中,降低单机单库的压力,提升读写性能。
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》