今天介绍一下 MySQL 数据库优化,从网上收集了 30 个我觉得以我的水平可以用得上(看得懂)的,主打一个接地气能落地,吃好就好(咱也不是 DBA 应付一下面试好了),优化方式实在是太多了,不用给自己增加负担,不信你可以问问 Kimi, 分分钟给你列上百个.
MySQL 优化可以从多个方面进行优化,当然对于研发来说,只需要关注 表结构 和 SQL 及索引即可,况且性价比最高。
- 优化成本:硬件>系统配置>数据库表结构>SQL及索引
- 优化效果:硬件<系统配置<数据库表结构<SQL及索引
对于MySQL优化一般遵从五个原则:
- 减少数据访问:设置合理的字段类型,启用压缩,通过索引访问等减少磁盘IO
- 减少数据返回:只返回需要的字段和数据分页处理,减少磁盘IO及网络IO
- 减少交互次数:批量操作,函数存储等减少数据库连接次数
- 减少服务器开销:尽量减少数据库排序操作以及全表查询
- 利用更多资源:使用表分区,可以增加并行操作,更大限度利用资源
总结到SQL优化中,就三点:
- 最大化利用索引;
- 尽可能避免全表扫描;
- 减少无效数据的查询;
SQL优化策略适用于数据量较大的场景下,如果数据量较小(10万内),没必要,哈哈。
SELECT 语法顺序
回顾一下查询关键词顺序。
SELECT
DISTINCT <select_list>
FROM <left_table>
<join_type> JOIN <right_table>
ON <join_condition>
WHERE <where_condition>
GROUP BY <group_by_list>
HAVING <having_condition>
ORDER BY <order_by_condition>
LIMIT <limit_number>
1. 尽量避免在字段开头模糊查询
字段开头模糊查询会导致数据库引擎放弃索引进行全表扫描
SELECT * FROM t WHERE username LIKE '%陈%'
-- 尽量在字段后面使用模糊查询
SELECT * FROM t WHERE username LIKE '陈%'
如果需求是要在前面使用模糊查询
- 使用MySQL内置函数INSTR(str,substr) 来匹配,作用类似于java中的indexOf()
- 数据量较大的情况,建议引用ElasticSearch、Solr等,亿级数据量检索速度秒级
- 退而求其次可以建立全文索引(FULLTEXT),配合全文模糊搜索(MATCH AGAINST)操作,而不是普通的 where 条件操作
看一个 match against 示例
-- MATCH (column1, column2, ...) AGAINST (search_keyword [search_modifier])
SELECT * FROM articles WHERE MATCH(content) AGAINST('MySQL');
注意:MySQL的MATCH AGAINST语句仅对MyISAM表类型支持,并且对大多数多字节字符集适用,但表意性语言如汉语、日语等由于没有词分界符,全文检索不支持(放弃吧,少年)。
2. 尽量避免使用 in
in 和 not in 语句会导致放弃索引走全表扫描
SELECT * FROM t WHERE id IN (2,3)
-- 可以使用 BETWEEN
SELECT * FROM t WHERE id BETWEEN 2 AND 3
如果是子查询,可以用exists代替
-- 不走索引
select * from A where A.id in (select id from B);
-- 走索引
select * from A where