【问题标题】:Best indexes for GROUP BY & equality query on joined tables对联接表进行 GROUP BY 和相等查询的最佳索引
【发布时间】:2020-12-18 12:50:31
【问题描述】:

我在 postgres 中有这个经常性的 SQL 查询:

SELECT b.name, COUNT(*)
FROM a JOIN b ON a.x = b.x
WHERE a.value = some_value
GROUP BY b.name;

(计算每个 b.name 的 a.value 出现次数)

有助于提高查询效率的最佳索引是什么?我假设 a.value 上的哈希索引会有所帮助。但是group by呢?有没有一些复合索引解决方案?还是另一种解决方案?

【问题讨论】:

  • 你真的想在这里加入吗?如果 A 中有多个行与(隐藏)连接条件匹配,则 B 中的行将被计​​算多次。
  • 这是 postgres,谢谢我编辑了帖子。关于连接,是的,重点是计算匹配的多次出现。自然连接只是代表主键-外键关系。
  • "自然连接只是代表主键 - 外键关系" - 不,它没有。它连接具有相同 name 的 所有 列,而不是基于声明的外键。
  • 对,我没有将它作为自然连接,我只是将它放在这篇文章中以简化查询,但我现在明白它也与问题相关,因此我将对其进行编辑。
  • a.value = some_value 的选择性如何?请在查询当前运行时显示EXPLAIN (ANALYZE) 计划。

标签: sql postgresql indexing group-by


【解决方案1】:

永远不要使用NATURAL JOIN。目前尚不清楚您的查询实际上在做什么。很容易出错。而且最重要的是,所谓的“自然”连接不使用使用外键关系明确声明的自然关系。

假设您的查询如下所示:

SELECT b.name, COUNT(*)
FROM a JOIN
     b 
     ON b.x = a.x
WHERE a.value = some_value
GROUP BY b.name;

在大多数数据库中,您需要以下索引:

  • a(value, x)
  • b(x, name)

【讨论】:

  • 对,我没有使用自然连接,我实际上使用的是你提到的 a.x=b.x 的 JOIN。我这样写是因为我认为它与问题无关——我的错。知道 x 是两个表上的主键,你的答案还是一样吗?另外,这些索引是b-tree还是hash?您将如何在 SQL 中实现它们? (抱歉,您可能已经很清楚了,但我不知道索引符号)
  • @DaltonicD 。 . .满足where 条件的索引将有所帮助,即使两者都是主键。如果x 已经是主键,则不需要第二个索引。索引的类型几乎没有区别;默认工作得很好。您的问题需要更多信息来区分索引类型(想到的一些问题是 where 条件是什么?表有多大?过滤多少?name 是唯一的)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多