项目线上随着业务量的增加,数据量增大,个别表上十万/百万,然后部分复杂sql就会变得很慢.并且发现了一个奇怪的问题.
有些sql通过 pagehelper 分页,查询总量时,将查询的列替换为count(0) 查询总量.例如:
原查询sql:
getDemoList:
select id,
name,
key_word,
punch_time,
salary_money,
bonus_money,
sex,
age
from demo
order by name
pagehelper 查询总量sql:
getDemoList_COUNT
select count(0)
from demo
order by name
也有些sql 是包含原sql,在外面添加 select count(0) from(原sql);例如:
getDemoList:
select IFNULL(SELECT examine
FROM demo_logs log
WHERE log.id = a.id
ORDER BY log.id DESC
LIMIT 1) AS log,
if(name = '王刚', 1, 2) as a,
CASE salary_money WHEN '10' THEN '10' ELSE '0' END AS salaryMoney,
id,
name,
key_word,
punch_time,
salary_money
from demo
order by name
pagehelper 查询总量sql:
getDemoList_COUNT
select count(0)
from (select IFNULL(SELECT examine FROM demo_logs log WHERE log.id = a.id ORDER BY log.id DESC LIMIT 1) AS log,
if(name = '王刚', 1, 2) as a,
CASE salary_money WHEN '10' THEN '10' ELSE '0' END AS salaryMoney,
id,
name,
key_word,
punch_time,
salary_money
from demo
order by name) tmp_count
这种现象很困惑,并且第二种查询总量的sql方式明显更加消耗性能,然后我就对他进行了排查,最后发现是 sql中 if函数 或者 ifnull函数的问题.
将第二个sql中的if/ifnull函数改为case when end 之后,查询总量方式就变成了替换查询列
测试结果:
变更后的原生sql
select (SELECT log.id
FROM demo_logs log
WHERE log.id = a.id
ORDER BY log.id DESC
LIMIT 1) AS log,
case name
when '王刚' then 1
else
2
end as a,
CASE salary_money WHEN '10' THEN '10' ELSE '0' END AS salaryMoney,
case id when null then 0 else id end id,
name,
key_word,
punch_time,
salary_money
from demo a
order by name
pagehelper 查询总量sql:
getDemoList_COUNT
SELECT count(0) FROM demo a
所以项目使用的是mybaits 集成pagehelper的话,不建议使用if/ifnull等这些函数,而是换成case when end.
这个只是我测试出来的pagehelper查询总量方式不同的原因,如果大家了解或知道什么其他的原因方式,欢迎留言.