Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database Oracle隐式分区修剪_Database_Oracle_Query Optimization - Fatal编程技术网

Database Oracle隐式分区修剪

Database Oracle隐式分区修剪,database,oracle,query-optimization,Database,Oracle,Query Optimization,我正试图在我的公司优化一个长期运行的存储过程。通过检查查询计划,我们似乎可以通过编写查询来实现更好的分区修剪,从而获得一些不错的收益。问题是,这样做似乎会创建一个非常冗长的查询。本质上,我们有一组表,这些表具有客户端和“子客户端”的外键。在许多情况下,客户机/子客户机之间不共享数据,因此我们对每个表的ID进行分区。下面是一个示例查询来说明我的意思: SELECT ... FROM CLIENT_PRODUCT cp INNER JOIN ORDER o ON o.product_id = cp.

我正试图在我的公司优化一个长期运行的存储过程。通过检查查询计划,我们似乎可以通过编写查询来实现更好的分区修剪,从而获得一些不错的收益。问题是,这样做似乎会创建一个非常冗长的查询。本质上,我们有一组表,这些表具有客户端和“子客户端”的外键。在许多情况下,客户机/子客户机之间不共享数据,因此我们对每个表的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,这些SQL在功能上不会改变返回的内容。这种相同的模式需要应用于许多联接(比示例更大)

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


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

请向我们展示包含索引的表定义您可能知道“应用程序有一个不变量,即产品的任何订单都必须属于同一个客户机和子客户机”,但数据库有吗?您的数据结构和约束是否向数据库表达了该业务规则?例如,您是否正在使用?除此之外,我不确定我是否理解您反对在连接条件中包含分区键。一般来说,我们的查询得益于尽可能的表达和明确。@APC我想我主要是问如何通过数据结构/约束向Oracle表达该业务规则。看起来引用分区非常适合我的用例。我想要一个“隐式”分区,因为代码库中有许多实例已经加入,但不包括分区键。由于键对于查询结果的正确性不是必需的,因此开发人员似乎不需要担心它。另外,如果可能的话,我希望避免重构。谢谢我们不能使用在线重新定义来实现引用分区。因此,您必须在停机时重建所有受影响的表。根据您在项目生命周期中的位置,重构PL/SQL可能是更容易的选择。