使用JOIN进行SELECT,其中连接的行为NULL

时间:2014-01-23 12:42:02

标签: mysql query-optimization

我正在尝试从表中选择在另一个表中没有对应关系的行。

为此,我目前正在使用LEFT JOINWHERE joined_table.any_column IS NULL,但我认为这不是最快的方法。

SELECT * FROM main_table mt LEFT JOIN joined_table jt ON mt.foreign_id=jt.id WHERE jt.id IS NULL

此查询有效,但正如我所说,我正在寻找更快的替代方案。

3 个答案:

答案 0 :(得分:1)

您的查询是对此的标准查询:

SELECT *
FROM main_table mt LEFT JOIN
     joined_table jt
     ON mt.foreign_id=jt.id
WHERE jt.id IS NULL;

你也可以试试这个:

SELECT mt.*
FROM main_table mt
WHERE not exists (select 1 from joined_table jt where mt.foreign_id = jt.id);

在某些版本的MySQL中,它可能会产生更好的执行计划。

答案 1 :(得分:1)

根据我使用MSSQL的经验,使用的语法(通常)会生成与WHERE NOT EXISTS()语法完全相同的查询计划,但这是mysql,所以我无法确定性能!!

那就是说,由于以下原因,我更喜欢使用WHERE NOT EXISTS()语法:

  • 更容易阅读。如果你说一点英语,任何人都可以推断出查询的含义
  • 它更加万无一失,我见过人们在NULL-able字段上测试NULL
  • 由于JOIN,它不会产生像'doubled-records'这样的副作用。如果引用的字段是唯一的没有问题,但我再次看到人们选择“密钥不足”导致主表对连接表进行多次点击的情况......当然他们使用DISTINCT再次解决了这个问题(aarrgg !!! =)

至于性能,请确保在引用的字段上有一个(唯一的)索引,如果可能的话,在两个表之间放置一个FK关系。查询方面我怀疑你可以从中榨取更多。

我的2美分。

答案 2 :(得分:0)

您正在运行的查询通常是最快的选项,只需确保您拥有mt.foreign_id和jt.id的索引。

您提到此查询更复杂,因此问题可能出现在查询的另一部分中。您应该检查执行计划以查看错误并进行修复。