【问题标题】:Use tables for filtering without fully merging all the results?在不完全合并所有结果的情况下使用表格进行过滤?
【发布时间】:2013-11-15 03:47:27
【问题描述】:

更新:Oracle 数据库,所有字段都已编入索引。 这是我在这里的第一篇文章,所以如果我没有正确提出这个问题,我深表歉意。

我有 3 张桌子 A、B、C。两个非常大(B,C)。我只需要符合 B 和 C 标准的 A 的结果。但是数据库 (Oracle) 最终尝试合并 AB 和 AC,整个查询的运行速度比我预期的要慢得多。

实际例子:

  • A- 客户:姓名、客户 ID
  • B- 订单:OrderId、CustomerId、OrderType
  • B- SupportTickets:TicketId、CustomerId、TicketType

以上所有字段均已编入索引。

在我的数据库中,每个客户的单个 OrderType 可能有 1000 个订单,每个客户的每个 TicketType 可能有 1000 个支持票。

  1. 我想列出 OrderType 为“squirrelcatcher”和 TicketType 为“ragingescapedsquirrel”的所有客户。
  2. 我只需要一个唯一的客户列表,我不需要包含来自 Orders 或 SupportTickets 的任何行。

我用一个简单的说法:

SELECT C.Name 
FROM 
 Customers C,
 JOIN Orders O ON O.CustomerId = C.CustomerId,
 JOIN SupportTickets S ON S.CustomerId = C.CustomerId
WHERE 
 O.OrderType='squirrelcatcher'
 AND S.TicketType='ragingescapedsquirrel'
GROUP BY 
 C.Name

当我运行查询时,它会超时。我不认为它应该花那么长时间来执行。我认为它正在尝试链接所有表甚至所有匹配的记录。但我认为它只需要为每个人找到一个匹配项,然后继续处理下一个客户。所以它应该运行得很快。

有什么提高性能的建议吗?

【问题讨论】:

  • mySQL?还是 SQL 服务器?还是甲骨文?
  • 请给出样本输入输出数据
  • 支持票是特定于订单还是仅针对客户?
  • 你在表上有索引吗?如果 CustomerID 在每个表上都有索引,那会有所帮助。
  • 关于样本数据..我不知道提供样本数据是否实用。小样本不会显示我收到的缓慢性能。

标签: sql oracle


【解决方案1】:

改用EXISTS

SELECT C.Name 
  FROM Customers C
 WHERE EXISTS (SELECT 1
                 FROM Orders O 
                WHERE O.CustomerId = C.CustomerId
                      AND O.OrderType='squirrelcatcher')
       AND EXISTS (SELECT 1
                     FROM SupportTickets S 
                    WHERE S.CustomerId = C.CustomerId
                          AND S.TicketType='ragingescapedsquirrel')

它可能会比内连接快,因为数据库只需要找到一个匹配的记录就可以满足条件。

【讨论】:

  • 这听起来正是我所需要的。我会尝试并报告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-26
  • 2012-02-03
  • 2012-03-29
  • 1970-01-01
  • 2019-11-19
  • 1970-01-01
相关资源
最近更新 更多