【问题标题】:Mysql select where not in tableMysql选择不在表中的位置
【发布时间】:2010-09-26 02:56:58
【问题描述】:

我有 2 个表(A 和 B)具有相同的主键。我想选择 A 中而不是 B 中的所有行。以下工作:

select * from A where not exists (select * from B where A.pk=B.pk);

但它看起来很糟糕(A 中只有 100k 行约 2 秒,B 中少 3-10k 行)

有没有更好的方法来运行它?也许作为左连接?

select * from A left join B on A.x=B.y where B.y is null;

根据我的数据,这似乎运行得稍微快一些(~10%),但总的来说呢?

【问题讨论】:

  • 你的意思是你的表 A 有 100k 行,表 B 有 100k 行?或者每个表中只有大约 300 行,这意味着 100,000 行扫描(或者,希望是索引扫描)。

标签: mysql join not-exists


【解决方案1】:

我认为您的最后陈述是最好的方法。你也可以试试

SELECT A.*    
from A left join B on 
    A.x = B.y
    where B.y is null

【讨论】:

  • 这没有任何意义。当 B.y 为空时,A.x=B.y 永远不会为真。您将获得 A 的所有行,而不仅仅是 B 中没有匹配行的行。
  • @Bill 但它确实有效!另外,它与上面列出的第二个语句完全相同。
  • @hamstar,是的,现在是正确的,将and 更改为where
  • @Smok "我觉得你最后的说法是最好的办法。你也可以试试..." ~ 你的不一样吗?
  • @BillKarwin 这很有意义。左连接至少包含每个 A 记录一次——每个匹配的 B 记录一次,如果没有匹配的 B,则在 B 列中包含一个 NULL。来自w3schools.com/sql/sql_join_left.asp:“LEFT JOIN 关键字返回左表中的所有行 (表1),与右表(表2)中的匹配行。没有匹配时,右侧的结果为NULL。具有数学 B 的 A 每次出现都会有一个非空 B.y,而没有 B 的 A 有一次出现空 B.y
【解决方案2】:

我使用第二个示例格式的查询。连接通常比相关子查询更具可扩展性。

【讨论】:

    【解决方案3】:

    我还使用带有“table2.id 为空”类型条件的左连接。

    当然似乎比嵌套查询选项更有效。

    【讨论】:

      【解决方案4】:

      联接通常更快(在 MySQL 中),但如果您发现索引方案仍然移动缓慢,您还应该考虑索引方案。通常,任何设置为外键的字段(使用 INNODB)都已经设置了索引。如果您使用的是 MYISAM,请确保 ON 语句中的所有列都已编入索引,并考虑将 WHERE 子句中的所有列添加到索引的末尾,以使其成为覆盖索引。这使引擎可以访问索引中所需的所有数据,从而无需再次往返原始数据。请记住,这会影响插入/更新/删除的速度,但会显着提高查询速度。

      【讨论】:

      • 实际上,Raul,您的编辑听起来好像您应该为 WHERE 子句中的列创建一个单独的索引。为了清楚起见,我打算将列添加到索引(覆盖索引),因此引擎不必为 WHERE 子句往返返回基本数据。抱歉不清楚。
      【解决方案5】:

      这对我帮助很大。 Joins 总是比子查询更快给出结果:

      SELECT tbl1.id FROM tbl1 t1
      LEFT OUTER JOIN tbl2 t2 ON t1.id = t2.id 
      WHERE t1.id>=100 AND t2.id IS NULL ;
      

      【讨论】:

        猜你喜欢
        • 2012-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-04
        • 2018-02-11
        • 1970-01-01
        • 1970-01-01
        • 2018-02-16
        相关资源
        最近更新 更多