高并发情况下查询的负载比较大,对于数据库有很多中优化方法,可以分库分表,读写分离,建立主从,部署多个节点分摊压力,也可以用如Elasticsearch,solr等其它方式。不过这主要是运维的层面去解决问题,如果开发时没有做好优化,那就只能以空间换时间,所以最原始的还是需要先把自身进行优化。
首先需要具备基本的概念
mysql的存储引擎,常用的几种
各种引擎有各自的特点,需要合理的使用
然后就是各种命令,比如EXPLAIN,SQL_NO_CACHE等,还有基本的sql语句,order by,group by having,sum,count,like,concat,instr,in等等,然后是索引的基础
索引经常被忽略,或者被误解,数据量小看不出效果,当数据量非常大时,体现的性能是惊人的,建立不好的索引有时对性能没有一丝帮助。
各存储引擎对索引的支持也不大相同,主要说一下常见的Btree索引,B树是一种多叉平衡查找树,简单说就是跟二叉树不一样的是,每个内节点有多个分支。有兴趣可以去了解下,平常我们这方面选择性不大,主要是如何让查询字段去命中索引。InnoDB的索引其实是把相应的字段抽取出来,存储真实数据到一张虚拟表中。
1、在做join查询的时候,on查询字段建立索引
2、where后的查询字段建立索引
3、order by字段建立索引
4、如果一个表多个查询字段,可以建立联合索引
5、id建立索引
注意:
like ‘123%’使用索引 like ‘%123%’不使用索引,可以使用instr替换,都会使用到索引,like对字符长度也有影响
select a.name from a left join b on a.id=b.aid order by name
name建立了索引的情况下name需写成a.name
除了建立索引,主要就是对sql语句的优化了,当然这里也有涉及到sql语句导致的索引失效
首先是要理解sql的业务场景,然后再优化:
1、where后面尽量不用函数
WHERE
DATE(a.time) >= '2021-07-13'
AND DATE(a.time) <= '2021-08-12'
就可以改成
WHERE
time >= '2021-07-13 00:00:00'
AND a.time)<= '2021-08-12 23:59:59'
2、让查询数据少
SELECT a.name,b.n from a LEFT JOIN (SELECT aid,sum(n) n from b GROUP BY b.aid) b on a.id=b.aid LIMIT 0,10
可以改成
SELECT a.name,(SELECT sum(n) from b where a.id=b.aid) n from a LIMIT 0,10