如何优化这条 sql

2023-06-26 13:51:25 +08:00
 fatyoung
查询字段 a ,要求在 T1 表有数据,在 T2 表没数据,这两张表都有 a 的普通索引,两张表数据量大致相同
我的 sql 如下
select a from T1 where a not in (select a from T2)

请教大家,有优化的空间吗?如何优化?
935 次点击
所在节点    问与答
7 条回复
liprais
2023-06-26 13:55:08 +08:00
用 exists
select a from T1 where not exists (select 1 from T2 where t2.a = t1.a)
monmon
2023-06-26 13:58:10 +08:00
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
2023-06-26 13:59:05 +08:00
left join T2
where T2.a is null

not in 挺差的
opengps
2023-06-26 14:00:09 +08:00
用左联接比用 in 靠谱
LeegoYih
2023-06-26 14:00:47 +08:00
改少查多的场景下:T1 表新增标识字段,新增 /删除 T2 表的时候,同时更新 T1 表对应数据的标识。
改多查少的场景下:用 not in/not exists 都可以
DissDoge
2023-06-26 16:20:43 +08:00
可以考虑使用 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
2023-06-26 16:53:30 +08:00
谢谢所有回复,受教了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/951761

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX