【问题标题】:Efficient way to get DISTINCT rows of Table A when JOINing with Table B与表 B 联接时获取表 A 的 DISTINCT 行的有效方法
【发布时间】:2014-07-24 02:37:14
【问题描述】:

简单的问题。给定示例表:

表 A:

id | type
---+-----
1  | A
2  | B
3  | C

表 B:

id | a_id | type
---+------+-----
1  | 1    | X
2  | 2    | Y
3  | 1    | X
4  | 3    | Z

(为了澄清问题,我省略了额外的列)

查询:

SELECT a.*
FROM a a
INNER JOIN b b ON b.a_id = a.id
WHERE b.type = 'X'

结果

id | type
---+-----
1  | A
1  | A

SQL 小提琴http://sqlfiddle.com/#!2/e6138f/1

但我只想拥有表 A 的不同行。我知道,我可以做 SELECT DISTINCT a.*,但是我们的表 A 大约有 40 列,而这个 SELECT 可以返回 100-10000 行。如果数据库必须比较每一列,那不是非常慢吗?

或者 MySQL 是否足够智能,只关注 DISTINCT 操作的主键?

提前感谢:)

【问题讨论】:

  • "或者 MySQL 是否足够智能,只关注 DISTINCT 操作的主键?" = 没有。 select distinct 是一个“行运算符”,它考虑每一行的所有部分。
  • 愚蠢的数据库。它应该简单地查找第一个unique(可能还有indexed)字段(在大多数情况下为id)并将其用于distinct。结果相同,但比较次数减少了 99%。 ...也许我应该切换到 Postgres,我可以说:just apply distinct to column x
  • 您可以告诉 sql dbs 仅使用一个字段或一组指定的字段来区分。您使用的是group by,而不是select distinct。在 Postgres 中 select distinct 是一样的; select distinct ON 不同。
  • 我刚刚测试过,你是对的:SELECT a.* FROM a a JOIN b b ON b.a_id = a.id GROUP BY a.id 有效。我一直认为我只能SELECT 也位于GROUP BY 语句中的字段以及这些列的聚合(如summax)。 ...我记得前段时间我在尝试使用 GROUP BY 并选择无法分组的字段时遇到 MySQL 错误。
  • 不要太激动,是的,您可以完全按照您在 MySQL 中所说的进行操作。但实际上你很可能会得到意想不到的结果。最好的做法是提名您分组依据的所有字段,然后通过聚合函数处理其他字段。捷径方法给出捷径结果。

标签: mysql sql join query-optimization distinct


【解决方案1】:

使用exists 而不是显式连接:

select a.*
from tablea a
where exists (select 1 from tableb b where b.a_id = a.id and b.type = 'x');

为了提高性能,请在 tableb(a_id, type) 上创建索引。

【讨论】:

    猜你喜欢
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多