在选择其他列时使用基于函数的索引
Utilize a function-based index while selecting additional columns
我有一个按预期工作的基于 Oracle 18c 函数的索引:
1.Create 一个接受 user-defined type 对象和 returns 坐标列表作为文本的自定义函数:
create or replace function endpoint_list(shape in sde.st_geometry) return varchar2
deterministic is
coord_list varchar2(4000);
begin
coord_list :=
--sde.st_geometry functions are notoriously slow.
sde.st_geometry_operators.st_x_f(sde.st_geometry_operators.st_startpoint_f(sde.st_geometry_operators.st_geometryn_f(shape,1))) || ',' ||
sde.st_geometry_operators.st_y_f(sde.st_geometry_operators.st_startpoint_f(sde.st_geometry_operators.st_geometryn_f(shape,1))) || ',' ||
sde.st_geometry_operators.st_x_f(sde.st_geometry_operators.st_endpoint_f( sde.st_geometry_operators.st_geometryn_f(shape,1))) || ',' ||
sde.st_geometry_operators.st_y_f(sde.st_geometry_operators.st_endpoint_f( sde.st_geometry_operators.st_geometryn_f(shape,1)));
return coord_list;
end;
2.Create 自定义函数上的基于函数的索引 (FBI):
create index atn_endpoint_list_idx on my_owner.active_transportation(my_owner.endpoint_list(shape));
3.Run在SELECT子句中使用FBI的查询:
select
endpoint_list(shape) as list
from
active_transportation --15,000 rows
where
endpoint_list(shape) is not null
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 727 | 299K| 50 (10)| 00:00:01 |
|* 1 | INDEX FAST FULL SCAN| ATN_ENDPOINT_LIST_IDX | 727 | 299K| 50 (10)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("my_owner"."ENDPOINT_LIST"("SHAPE") IS NOT NULL)
FBI 按预期工作。当我 select endpoint_list(shape)
作为列时,查询使用索引,将 运行 时间从 65 秒减少到 .09 秒。好
除了 selecting endpoint_list(shape)
,我还想 select 来自 table 的其他列,例如 OBJECTID 列:
select
objectid, --Note: OBJECTID has a index of it's own (unique).
endpoint_list(shape) as list
from
active_transportation
where
endpoint_list(shape) is not null
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 727 | 299K| 181 (4)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| ACTIVE_TRANSPORTATION | 727 | 299K| 181 (4)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("my_owner"."ENDPOINT_LIST"("SHAPE") IS NOT NULL)
现在,没有使用联邦调查局。查询改为进行完整的 table 扫描,这不是我想要的。
问题:
如何在 select 添加其他列时利用基于函数的索引?
解决方案似乎是将附加列 (OBJECTID) 添加到索引中 — 作为复合索引:
create index atn_endpoint_list_idx on
my_owner.active_transportation(my_owner.endpoint_list(shape),OBJECTID);
--
现在,正在使用 FBI:
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 727 | 299K| 53 (10)| 00:00:01 |
|* 1 | INDEX FAST FULL SCAN| ATN_ENDPOINT_LIST_IDX | 727 | 299K| 53 (10)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("my_owner"."ENDPOINT_LIST"("SHAPE") IS NOT NULL)
我有一个按预期工作的基于 Oracle 18c 函数的索引:
1.Create 一个接受 user-defined type 对象和 returns 坐标列表作为文本的自定义函数:
create or replace function endpoint_list(shape in sde.st_geometry) return varchar2
deterministic is
coord_list varchar2(4000);
begin
coord_list :=
--sde.st_geometry functions are notoriously slow.
sde.st_geometry_operators.st_x_f(sde.st_geometry_operators.st_startpoint_f(sde.st_geometry_operators.st_geometryn_f(shape,1))) || ',' ||
sde.st_geometry_operators.st_y_f(sde.st_geometry_operators.st_startpoint_f(sde.st_geometry_operators.st_geometryn_f(shape,1))) || ',' ||
sde.st_geometry_operators.st_x_f(sde.st_geometry_operators.st_endpoint_f( sde.st_geometry_operators.st_geometryn_f(shape,1))) || ',' ||
sde.st_geometry_operators.st_y_f(sde.st_geometry_operators.st_endpoint_f( sde.st_geometry_operators.st_geometryn_f(shape,1)));
return coord_list;
end;
2.Create 自定义函数上的基于函数的索引 (FBI):
create index atn_endpoint_list_idx on my_owner.active_transportation(my_owner.endpoint_list(shape));
3.Run在SELECT子句中使用FBI的查询:
select
endpoint_list(shape) as list
from
active_transportation --15,000 rows
where
endpoint_list(shape) is not null
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 727 | 299K| 50 (10)| 00:00:01 |
|* 1 | INDEX FAST FULL SCAN| ATN_ENDPOINT_LIST_IDX | 727 | 299K| 50 (10)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("my_owner"."ENDPOINT_LIST"("SHAPE") IS NOT NULL)
FBI 按预期工作。当我 select endpoint_list(shape)
作为列时,查询使用索引,将 运行 时间从 65 秒减少到 .09 秒。好
除了 selecting endpoint_list(shape)
,我还想 select 来自 table 的其他列,例如 OBJECTID 列:
select
objectid, --Note: OBJECTID has a index of it's own (unique).
endpoint_list(shape) as list
from
active_transportation
where
endpoint_list(shape) is not null
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 727 | 299K| 181 (4)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| ACTIVE_TRANSPORTATION | 727 | 299K| 181 (4)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("my_owner"."ENDPOINT_LIST"("SHAPE") IS NOT NULL)
现在,没有使用联邦调查局。查询改为进行完整的 table 扫描,这不是我想要的。
问题:
如何在 select 添加其他列时利用基于函数的索引?
解决方案似乎是将附加列 (OBJECTID) 添加到索引中 — 作为复合索引:
create index atn_endpoint_list_idx on
my_owner.active_transportation(my_owner.endpoint_list(shape),OBJECTID);
--
现在,正在使用 FBI:
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 727 | 299K| 53 (10)| 00:00:01 |
|* 1 | INDEX FAST FULL SCAN| ATN_ENDPOINT_LIST_IDX | 727 | 299K| 53 (10)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("my_owner"."ENDPOINT_LIST"("SHAPE") IS NOT NULL)