mybatis 集成pagehelper 分页前查询总量方式,是包含原sql,在外面添加 select count(0) from();或者将查询的列替换为count(0).

项目线上随着业务量的增加,数据量增大,个别表上十万/百万,然后部分复杂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查询总量方式不同的原因,如果大家了解或知道什么其他的原因方式,欢迎留言.

你可能感兴趣的:(优化,mysql,sql函数,mybatis,pagehelper,sql优化,java,sql)