【问题标题】:MySQL INNER JOIN vs "WHERE id IN ()"MySQL INNER JOIN 与“WHERE id IN ()”
【发布时间】:2014-03-03 10:30:41
【问题描述】:

我有一个文档权限表,我希望为用户选择一页文档。 问题是,一个用户可以通过多个组被允许访问一个文档,因此我们可能有多个X records for X documents 供用户使用。

我尝试使用子查询进行分页,但 MySQL 不喜欢 LIMIT in the subquery。

我面临两个主要选择:

  1. SELECT perm.* FROM
    (SELECT DISTINCT document_id FROM permissions WHERE .... LIMIT...) ids
    INNER JOIN
    (SELECT fields FROM permissions WHERE ....) perms
    ON ids.document_id = perms.document_id
    
  2. 使用 Java 进行连接 - 首先读取文档 ID,然后在如下查询中使用它们:

    SELECT fields FROM permissions WHERE .... AND document_id IN([specific document_ids previously read])
    

什么会更有效率?

【问题讨论】:

  • 你想找到这个answer可能对你有帮助。
  • MySQL 不喜欢子查询,也不喜欢你给它设置限制。限制本身是特定于数据库的,因此它不是标准。您可以使用 setMaxResults 作为替代方案。
  • 修改您的查询,它可以相当简单。您确定需要查询 SAME 表两次吗?您应该能够在一个 SELECT 中应用所有 WHERE 条件

标签: mysql join


【解决方案1】:

您的问题中有一些不同的问题。首先:

1:我不太明白你在查询中做了什么,但是限制子句必须在查询的末尾,所以你可以试试

select * from A join B on A.id = B.id limit 10

这应该有效。更多信息:

https://dev.mysql.com/doc/refman/5.0/en/select.html

2:Join vs. IN 子句:IN 子句的性能应该总是比 join 差。想象一下:

select * from A where A.id in (select id from B)

这将对 B 表(select id from B 子查询)进行全面扫描,然后对 A 进行另一次全面扫描以尝试匹配结果。

然而,

select * from A join B on A.id = B.id

应该在两个表之间做一个哈希连接,如果你的计划是正确的,id 将是一个索引列,所以它应该会更快(并且对它们都不做全扫描)

【讨论】:

  • RE 1:事情是,我想要超过 10 行,我想要前 10 个文档 ID 的所有相关行。两个查询中的条件基本相同。由于它是一个非常大的表,我希望避免使用哈希连接。 RE 2:您编写的第一个查询并不是我的意思,因为我希望从 Java 中只调用一次“子查询”,然后将特定的 ID 放入 IN 子句中。那会怎么样?
猜你喜欢
  • 1970-01-01
  • 2021-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-15
  • 2012-02-16
  • 1970-01-01
相关资源
最近更新 更多