0

更新: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

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

有什么建议可以提高性能吗?

4

1 回答 1

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')

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

于 2013-11-14T19:43:11.777 回答