V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
fatyoung
V2EX  ›  问与答

如何优化这条 sql

  •  
  •   fatyoung · 315 天前 · 811 次点击
    这是一个创建于 315 天前的主题,其中的信息可能已经有所发展或是发生改变。
    查询字段 a ,要求在 T1 表有数据,在 T2 表没数据,这两张表都有 a 的普通索引,两张表数据量大致相同
    我的 sql 如下
    select a from T1 where a not in (select a from T2)

    请教大家,有优化的空间吗?如何优化?
    7 条回复    2023-06-26 16:53:30 +08:00
    liprais
        1
    liprais  
       315 天前   ❤️ 1
    用 exists
    select a from T1 where not exists (select 1 from T2 where t2.a = t1.a)
    monmon
        2
    monmon  
       315 天前   ❤️ 1
    NOT IN 操作符子查询,在大数据集上运行可能会非常慢,当子查询返回大量数据时,NOT IN 的性能可能会下降,因为它需要对子查询返回的每个值进行比较。
    可以考虑使用`NOT EXISTS`或者`LEFT JOIN/IS NULL`来提高性能

    ```mssql
    SELECT a FROM T1
    WHERE NOT EXISTS (SELECT 1 FROM T2 WHERE T1.a = T2.a);
    ```

    ```mysql
    SELECT T1.a FROM T1
    LEFT JOIN T2 ON T1.a = T2.a
    WHERE T2.a IS NULL;
    ```
    8355
        3
    8355  
       315 天前   ❤️ 1
    left join T2
    where T2.a is null

    not in 挺差的
    opengps
        4
    opengps  
       315 天前   ❤️ 2
    用左联接比用 in 靠谱
    LeegoYih
        5
    LeegoYih  
       315 天前   ❤️ 1
    改少查多的场景下:T1 表新增标识字段,新增 /删除 T2 表的时候,同时更新 T1 表对应数据的标识。
    改多查少的场景下:用 not in/not exists 都可以
    DissDoge
        6
    DissDoge  
       315 天前   ❤️ 2
    可以考虑使用 LEFT JOIN 和 NULL 值判断来优化,避免使用子查询。
    SELECT T1.a
    FROM T1
    LEFT JOIN T2 ON T1.a = T2.a
    WHERE T2.a IS NULL;
    使用 LEFT JOIN 将 T1 表和 T2 表连接起来,根据 a 列进行匹配。在 WHERE 子句中,筛选出 T2.a 为 NULL 的记录,这表示在 T1 表中有数据但在 T2 表中没有数据。这种方式比使用子查询效率更高,可以减少查询时间。
    另外,确保在 T1 表和 T2 表的 a 列上都创建了索引,这样可以进一步提升查询性能。
    fatyoung
        7
    fatyoung  
    OP
       315 天前
    谢谢所有回复,受教了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5874 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 02:53 · PVG 10:53 · LAX 19:53 · JFK 22:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.