首页 > 解决方案 > Oracle 隐式分区修剪

问题描述

我正在尝试优化我公司长期运行的存储过程。通过检查查询计划,看起来我们可以通过编写查询来获得一些不错的收益,以实现更好的分区修剪。问题是,这样做似乎会创建一个非常冗长的查询。本质上,我们有一堆表,它们具有客户端和“子客户端”的外键。在许多情况下,数据不会在客户端/子客户端之间共享,因此我们对每个表的这些 ID 进行分区。这是一个示例查询来说明我的意思:

SELECT ...
FROM CLIENT_PRODUCT cp
INNER JOIN ORDER o ON o.product_id = cp.id
INNER JOIN PRICE_HISTORY ph on ph.product_id = cp.id
WHERE cp.id = ?

所有表都有一个引用客户端和子客户端的外键。同一个客户端产品不能属于两个不同的客户端或子客户端(对不起,这个例子是使用组合表,有点做作)

我可以通过执行以下操作来改进分区修剪:

SELECT ...
FROM CLIENT_PRODUCT cp
INNER JOIN ORDER o ON o.product_id = cp.id and o.client_id = l_client_id and o.sub_client_id = l_sub_client_id
INNER JOIN PRICE_HISTORY ph on ph.product_id = cp.id and ph.client_id = l_client_id and ph.sub_client_id = l_sub_client_id
WHERE cp.id = ? and cp.client_id = l_client_id and cp.sub_client_id = l_sub_client_id

通过这个更改,我只是明确说明 Oracle 可以为每个连接查看哪些分区。这感觉很恶心,因为我添加了一堆大部分重复的 SQL,它们在功能上不会改变返回的内容。需要将相同的模式应用于许多连接(大于示例)

我知道我们的应用程序有一个不变量,即产品的任何订单都必须属于同一个客户和子客户。同样,任何价格历史项目必须与产品属于同一客户和子客户。同样的想法适用于许多表对。在理想情况下,Oracle 将能够从连接中的其他表中推断出每个连接的客户端和子客户端,因为该不变性。它似乎没有这样做(我知道我的特定不变量并不适用于所有人)。有没有一种方法可以让 Oracle 进行这种隐式分区修剪,而无需添加所有这些附加条件?看起来这会在代码库中增加很多价值,并消除对所有这些“不必要的”显式连接的需要。

还有一种可能性是我完全过度思考/误解了这一点,所以其他建议会很好。

标签: databaseoraclequery-optimization

解决方案


推荐阅读