我在Oracle 9i中有一个自引用表,以及一个从中获取数据的视图:
CREATE OR REPLACE VIEW config AS
SELECT c.node_id,
c.parent_node_id,
c.config_key,
c.config_value,
(SELECT c2.config_key
FROM vera.config_tab c2
WHERE c2.node_id = c.parent_node_id) AS parent_config_key,
sys_connect_by_path(config_key, '.') path,
sys_connect_by_path(config_key, '->') php_notation
FROM config_tab c
CONNECT BY c.parent_node_id = PRIOR c.node_id
START WITH c.parent_node_id IS NULL
ORDER BY LEVEL DESC
该表存储PHP应用程序的配置。现在我需要在oracle视图中使用相同的配置。
我想通过路径从视图中选择一些值,但遗憾的是这需要0,15秒,因此这是不可接受的成本。
SELECT * FROM some_table
WHERE some_column IN (
SELECT config_value FROM config_tab WHERE path = 'a.path.to.config'
)
首先我想到了sys_connect_by_path上的函数索引,但这是不可能的,因为它还需要CONNECT BY子句。
有什么建议我如何在'config'视图中模拟路径列上的索引?
答案 0 :(得分:2)
如果您的数据在config_tab
中没有经常更改,则可以使用与您的视图具有相同查询的materialized view。然后,您可以索引实体化视图的path
列。
CREATE MATERIALIZED VIEW config
REFRESH COMPLETE ON DEMAND
AS <your_query>;
CREATE INDEX ix_config_path ON config (path);
由于这是一个复杂的查询,因此每次更新基表时都需要对物化视图执行full refresh,以便MV中的数据不会过时。
path
将被定义为VARCHAR2(4000)
。您可以限制此列的大小以便对其进行索引。在您的查询中,请将sys_connect_by_path(...)
替换为SUBSTR(sys_connect_by_path(..., 1, 1000)
,例如。dbms_job
的一项功能)。这更复杂,因为您必须检查每个事务只触发一次作业(例如使用包变量)。同样,只有在不经常更新基表的情况下,这才是实用的。