mysql

sql优化经验

2021-02-26  本文已影响0人  修行者12138

大部分表都有表示逻辑删除的字段,比如is_valid,Y为有效N为无效,写sql时大部分都会带上这个字段,所以建索引时,建议带上这个字段。

比如student表有name列,如果只对name列建索引,where name = ‘xxx’ and is_valid = ‘Y’,索引不生效,应该建(name, is_valid)联合索引

尽量少在mysql做函数计算,容易成为性能瓶颈,建议把函数计算上移到应用层,即java代码。

比如需要查找时间入参前一天的数据,可以这样写: where date = date_add(#{时间入参}, interval -1 DAY),也可以在java层把时间入参减一天,再传到mysql,这样就是 where date = #{时间入参}

尽量使用覆盖索引,覆盖索引不需要回表(回表需要随机IO),explain的extra列有using index表示用上了覆盖索引。

假设有一个学生表,有id name age is_valid四个列,现在有一个根据年龄查询有效姓名的功能,想要用上覆盖索引,索引该怎么建?

答案: KEY idx_age_valid_name (age,is_valid,name)

explain select name from student where age = 30 and is_valid = 'Y';

image.png

如果是select * from a join b where xxx这种写法,会对a和b求笛卡尔积,然后根据条件过滤数据,笛卡尔积非常大,性能极差,因此最好写成select * from a join b on xxx这种写法,结果完全等价。

注意:只有join可以这样等价替换,left join和right join不行

select部分有子查询时,最好自定义PageHelper分页

select
(select a from t1 where xxx) as a,
(select b from t2 where xxx) as b
from t3

使用PageHelper时,会先count一下原sql统计总数用于分页。
对于上面这种sql,select count(上面的sql)与select count(*) from t3结果一样,但是前者耗时更长,如果用PageHelper分页,默认使用前者,需要自定义为后者。
假设原sql的标签为<select id='queryT3'>,可以写一个<select id='queryT3_COUNT>',PageHelper会根据_COUNT后缀判断是否为自定义count函数。

深分页问题
先查id,再用in查数据

上一篇 下一篇

猜你喜欢

热点阅读