【问题标题】:Oracle SQL self join performanceOracle SQL 自联接性能
【发布时间】:2020-03-13 11:05:49
【问题描述】:

假设我有一个名为 order 的表,其中包含以下数据。我需要得到 customer_name 和 no。他们下的订单。

表名:顺序

id | customer_name | item
1  | Siddhant      | TV
2  | Siddhant      | Mobile
3  | Sankalp       | Football

期望的输出:

customer_name | no_of_orders
Siddhant      | 2
Sankalp       | 1

我尝试了以下 2 个查询以获得结果:

select customer_name, count(customer_name) as no_of_orders
from order
group by customer_name;

这给了我正确的结果,但运行大约需要 10.5 秒

select ord.customer_name, count(ord1.customer_name) as no_of_orders
from order ord
inner join order ord1 on ord1.customer_name = ord.customer_name
group by ord.customer_name;

这给了我结果中的平方(正确计数),但运行时间约为 2 秒。我可以得到平方根来得到实际的计数。

我理解为什么第二个查询在输出中给出实际计数的平方,但有人可以解释为什么它与第一个查询相比运行得如此之快?

PS:我在 Oracle SQL Developer 中运行这些。

【问题讨论】:

  • “有人能解释一下为什么它比第一个查询运行得这么快吗?”这可能只是运行两个查询的产物。第一个查询完成了将行从磁盘读取到内存的所有工作,然后第二个查询从中受益并从内存中读取。这被称为暖缓存效应。除此之外,请阅读this answer on asking Oracle database performance question
  • customer_name 列上是否有任何索引?如果您在第一次查询中使用count(1) 而不是count(customer_name),那么时间是几点?
  • @APC,我先跑了第二个。
  • @Tejash,与 count(1) 没有区别。是的,customer_name 上有一个索引。
  • @Marmite 是正确的。我在两个查询的结果之上添加了一个 select count(*),而 self join 则花费了更多时间,因为现在它必须先获取所有记录才能进行计数。

标签: sql oracle performance self-join


【解决方案1】:

第一个版本是您应该在这里使用的版本:

SELECT customer_name, COUNT(customer_name) AS no_of_orders
FROM "order"
GROUP BY customer_name;

没有WHEREHAVING 子句,在这里添加索引可能没有太大帮助,因为Oracle 基本上必须接触表中的每条记录才能进行聚合。至于为什么第二个版本看起来更快,我推测您使用的基准测试并不具有代表性,因为它们基于相当小的表大小。如果您将表数据扩展到数万行,我预测第一个版本会快得多。

【讨论】:

  • 我也认为第一个应该更快。仅供参考,我在此表中有 15063819 条记录。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-29
  • 1970-01-01
  • 2020-07-28
  • 2012-02-23
  • 2018-08-27
  • 2021-03-13
  • 1970-01-01
相关资源
最近更新 更多