美文网首页开发记录
Sql 优化 后如何确保结果一致啊

Sql 优化 后如何确保结果一致啊

作者: 叮咣铛 | 来源:发表于2019-04-12 21:43 被阅读0次

同事群里发慢sql优化记录

手痒打开一个看看,尝试下

速度提起来了

那么问题来了,你怎么保证优化过的sql结果和之前是一致的?

Sql 优化 后如何确保结果一致啊

即:你没改变他的逻辑

google告诉我 用minus ,对不起Mysql不支持

中间也想过自己搞个Java 多线程 加limit关键字 ,切段比较?感觉太笨拙了,
手里有锤子满世界都是钉子也不行啊

 So
Mysql minus  替代品:

left join  .... is null

先看两个表结构


t1.png t2.png

同样的表结构,
内容 前三条一致,最后一条不同

目标: 找出不同记录数

方式:

select s1.region_id ,s1.name, s2.region_id, s2.name 

from sales_region s1

left join sales_region_new s2 

on s1.region_id = s2.region_id
t3.png

oye!

如果愉快的加个 s2.region_id is null 判断:

select s1.region_id ,s1.name, s2.region_id, s2.name 
from sales_region s1

left join sales_region_new s2 

on s1.region_id = s2.region_id

where s2.region_id is null

类似 minus的效果


t4.png

再直观一点:告诉我 s1 中有 而s2没有的 记录条数

SELECT
COUNT(*) AS s1Have_s2None_counts
FROM
sales_region s1
LEFT JOIN
sales_region_new s2 ON s1.region_id = s2.region_id
WHERE
s2.region_id IS NULL


t5.png

好了,铺垫完毕

回到咱们面对的问题:

如何保证两条sql 返回的结果是一致的?

即 ,当你优化系统中的慢sql时候,
如何验证你修改后的sql和修改前的sql ,结果一致

即使你优化了速度,但不能把逻辑搞错了

例如:

SELECT 
    *
FROM
    c_alarm_data_t
WHERE
    create_date > '2019-03-13'
        AND sensor_no != 'E11'
        AND terminal_no IN (SELECT 
            terminal_no
        FROM
            v_terminal_t
        WHERE
            organization_no IN (SELECT DISTINCT
                    organization_no
                FROM
                    v_terminal_t
                WHERE
                    terminal_no IN (SELECT 
                            terminal_no
                        FROM
                            f_dt_limitsgp_limits
                        WHERE
                            dt_limitsgp_id IN (SELECT 
                                    dt_limitsgp_id
                                FROM
                                    f_dt_user_datalimitsgp
                                WHERE
                                    userid = 'userid99998888test'))));
image8.png

结果有260w, 耗时 8.2s , 这里只展示了100条

优化后(去掉莫名其妙的自己in 自己):

    *
FROM
    c_alarm_data_t
WHERE
    create_date > '2019-03-13'
        AND sensor_no != 'E11'
        AND terminal_no IN 
        
        -- (SELECT 
--             terminal_no
--         FROM
--             v_terminal_t
--         WHERE
--             organization_no IN (SELECT DISTINCT
--                     organization_no
--                 FROM
--                     v_terminal_t
--                 WHERE
--                     terminal_no IN 
--                     
                    (SELECT 
                            terminal_no
                        FROM
                            f_dt_limitsgp_limits
                        WHERE
                            dt_limitsgp_id IN (SELECT 
                                    dt_limitsgp_id
                                FROM
                                    f_dt_user_datalimitsgp
                                WHERE
                                    userid = 'userid99998888test'));
image019.png

用时0.019s

速度提升431倍!!!

Sql 优化 后如何确保结果一致啊

sql 区别如下:


imageDiff.png

验证两个sql结果一致:

SELECT 
    COUNT(t1.alarm_id)
FROM
    (SELECT 
        *
    FROM
        c_alarm_data_t
    WHERE
        create_date BETWEEN '2019-04-02 12:00:00' AND '2019-04-02 12:00:01'
            AND sensor_no != 'E11'
            AND terminal_no IN (SELECT 
                terminal_no
            FROM
                f_dt_limitsgp_limits
            WHERE
                dt_limitsgp_id IN (SELECT 
                        dt_limitsgp_id
                    FROM
                        f_dt_user_datalimitsgp
                    WHERE
                        userid = 'userid99998888test'))
    LIMIT 5) AS t1
        LEFT JOIN
    (SELECT 
        *
    FROM
        c_alarm_data_t
    WHERE
        create_date BETWEEN '2019-04-02 12:00:00' AND '2019-04-02 12:00:01'
            AND sensor_no != 'E11'
            AND terminal_no IN (SELECT 
                terminal_no
            FROM
                v_terminal_t
            WHERE
                organization_no IN (SELECT DISTINCT
                        organization_no
                    FROM
                        v_terminal_t
                    WHERE
                        terminal_no IN (SELECT 
                                terminal_no
                            FROM
                                f_dt_limitsgp_limits
                            WHERE
                                dt_limitsgp_id IN (SELECT 
                                        dt_limitsgp_id
                                    FROM
                                        f_dt_user_datalimitsgp
                                    WHERE
                                        userid = 'userid99998888test'))))
    LIMIT 5) AS t2 ON t1.alarm_id = t2.alarm_id
WHERE
    t2.alarm_id IS NULL;
imageCnt0.png

为了提高速度,sql做了轻微修改,
时间段缩小为1s
limit 5 只取5条
即使这样,这个判定还要8.1s...

做个记录吧,谁有更好的方案,欢迎指教

话说 简书为何没有标签功能?

相关文章

  • Sql 优化 后如何确保结果一致啊

    同事群里发慢sql优化记录 手痒打开一个看看,尝试下 速度提起来了 那么问题来了,你怎么保证优化过的sql结果和之...

  • 如何确保案件结果最优化

    先举一个之前学篮球投篮的例子:大学室友是校队的,也经过专业的训练,他教我投篮的流程是这样的,先教我投篮时拿球的姿势...

  • 性能调优之SQL优化

    性能调优之SQL优化如何加快查询速度?1、升级硬件2、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的...

  • mysql优化思路总结

    1.优化的目的2.如何定位问题sql,使用什么工具3.如何sql层面优化4.如何应用层层面优化 explain 命...

  • MySQL优化OR

    原SQL: 优化后:

  • mysql 知识碎片

    查看优化后最终执行的sql 这两条sql要同时执行,才能通过show warnings查出优化后的sql语句。

  • MySql优化整理(多本书精华汇总集合)

    如何优化SQL语句? select version() -- 查看SQL当前版本 | |- 1) 通过 show ...

  • 常用sql优化2019-09-27

    sql优化 sql优化.................................................

  • MySql 优化

    SQL优化 通过show status命令了解各种sql的执行效率 结果 Com_select:执行select操...

  • MySql 全方位基础优化

    SQL优化 通过show status命令了解各种sql的执行效率 结果 Com_select:执行select操...

网友评论

    本文标题:Sql 优化 后如何确保结果一致啊

    本文链接:https://www.haomeiwen.com/subject/imnhwqtx.html