在某次业务逻辑中写到如下逻辑:查询学校级别的未拦截弹窗记录。而弹窗设备表(t_block_blacklist_device)有四种类型(1:学校级黑名单 2:设备级别黑名单 3:略 4:学校级白名单 注:从来没有被加入黑名单或白名单不存在这张表中)。弹窗弹出次数表为t_block_count。于是写下以下sql:查询弹窗弹出次数表的次数,排除掉出现在弹窗设备表中学校级的弹窗id(c_block_id中排除掉c_blacklist_id)
SELECT
SUM( bc.c_count ) AS blockNum
-- ....
FROM
t_block_count AS bc
WHERE
bc.c_school_code = '****'
AND bc.c_block_id NOT IN (
SELECT
bbd2.c_blacklist_id
FROM
t_block_blacklist_device AS bbd2
WHERE
bbd2.c_school_code = '****'
AND bbd2.c_enabled = 1
AND bbd2.c_type IN ( 1, 4 )
)
GROUP BY
bc.c_block_id
ORDER BY
blockNum DESC;
explain结果
得到sql后发现not in加子查询在数据量很高的时候性能很差,于是参考网上和《高性能mysql》优化方案,写出not exits和left join的方案,并对比其性能。
not exits方案:
SELECT
SUM( bc.c_count ) AS blockN