具有联接的精确在线查询运行时间超过 15 分钟
Exact Online query with joins runs more than 15 minutes
我正在使用以下查询:
set use-result-cache false
set use-http-cache false
create or replace table settings@inmemorystorage
as
select '29676ec4-61b5-45eb-a5a3-6feffe03d1d3' sor_id
, '[[Exploded]]' exploded_signal_text
, '{res:itgen_eol_sales_order}' entity_name_singular
, '{res:itgen_eol_sales_orders}' entity_name_plural
from me
select ...
from settings@inmemorystorage stg
left
outer
join ExactOnlineREST..salesorders sor
on sor.orderid = stg.sor_id
left
outer
join ExactOnlineREST..salesorderlines soe
on soe.orderid = stg.sor_id
left
outer
join BillOfMaterialItemDetails bom
on bom.billofmaterialitemdetails_billofmaterial_item_id_attr_guid = soe.item
left
outer
join ExactOnlineREST..items itm
on itm.ID = bom.item_id_attr_guid
left
outer
join ExactOnlineREST..itemsread itr
on itr.code = bom.item_code_attr
where sor.orderid is not null
and itm.class_10 in ('A', 'D', 'M', 'S', 'Z')
从 Exact Online 检索数据。在我的测试环境中,运行 大约需要 1 秒才能在销售订单上应用 Material 爆炸清单(在 Exact Online 的 XML 和 REST API 上大约读取 5 次).但是,在客户站点上 运行 超过 15 分钟。好像和Material的Bill中使用的items(articles)的检索有关;在我的测试环境中大约有 100 个项目,而客户站点有 250.000 个项目。
但是,此查询用于交互式程序,应该 运行 在 2.5 秒内。
我试图结合 itemsread 和 items 来限制检索的项目,但是它们有不同的字段,这两个表都需要。
如何针对大量数据优化此查询以运行更快?
问题出在第二个查询中:项目很多,而 Exact Online 的 API 吞吐量可能是每秒 300 个项目。所以这一切都没有改变。
有两条备选路线:
- 优化查询
- 使用缓存
查询优化确保了在首次使用和后续使用时的出色性能和极少的资源占用。使用缓存可以缩短第二次使用的响应时间,但需要比优化查询更多的资源。
优化在线精确查询
要优化查询,您需要指示优化器如何更正确地处理连接,因为 Exact Online 默认情况下没有可用的统计信息和参考数据。我会添加以下提示:
select /*+ join_set(soe, orderid, 100) join_set(itm, id, 100) join_set(itr, code, 100) */ ...
from settings@inmemorystorage stg
...
第一个提示 join_set(soe, orderid, 100)
指示优化器将连接算法从散列连接更改为索引循环,以便在 orderid
上连接 soe
(右侧)时执行路径中上一步最多返回 100 行。在这种情况下,将从 settings
返回一行。 itm
和 itr
.
上的连接也是如此
对于大型 Exact Online 环境,这将确保在销售订单行数少于 60 行时始终有 5 次查找。这通常需要 1 秒。
使用缓存(Data Cache)
当您将 PostgreSQL、SQL 服务器、Oracle 或 MySQL 数据库配置为 Invantive Data Cache 支持数据库提供程序时,您可以获得部分查询的结果存储在普通数据库中。当数据缓存仍然足够 "fresh".
时,优化器会自动使用 ANSI SQL 查询此普通数据库
例如:
select /*+ ods(true, interval '7 days') */ ...
告诉优化器在不超过 7 天前将数据放入数据缓存时对所有 Exact Online 数据使用数据缓存。当超过 7 天时,它创建一个新版本,将其存储在数据缓存中并使用它。
当您需要在 Exact Online 中包含近乎实时的更改时,您将必须配置数据复制。然后它通过网络挂钩检索所有 insert/update/delete 事件并将它们应用于您的数据缓存。但是缓存可能仍然有 30 分钟的历史,因为传播可能需要一些时间。
性能比没有缓存和没有优化好很多。一般来说,250.000 个项目的吞吐量会好 1.000 倍,因此与使用 250 个项目相当。鉴于 Exact Online 的典型页面大小为 60,感觉为 5 + 5 + 3 = 13 I/Os,因此大约 2,6 秒,接近 2,5 秒的给定边界。
请注意,您正在使用的材料清单 table 将永远不会使用索引查找,因为此时没有可用的索引。因此,如果您的所有产品都有大量物料清单,则必须进行数据缓存以获得合理的性能。
我正在使用以下查询:
set use-result-cache false
set use-http-cache false
create or replace table settings@inmemorystorage
as
select '29676ec4-61b5-45eb-a5a3-6feffe03d1d3' sor_id
, '[[Exploded]]' exploded_signal_text
, '{res:itgen_eol_sales_order}' entity_name_singular
, '{res:itgen_eol_sales_orders}' entity_name_plural
from me
select ...
from settings@inmemorystorage stg
left
outer
join ExactOnlineREST..salesorders sor
on sor.orderid = stg.sor_id
left
outer
join ExactOnlineREST..salesorderlines soe
on soe.orderid = stg.sor_id
left
outer
join BillOfMaterialItemDetails bom
on bom.billofmaterialitemdetails_billofmaterial_item_id_attr_guid = soe.item
left
outer
join ExactOnlineREST..items itm
on itm.ID = bom.item_id_attr_guid
left
outer
join ExactOnlineREST..itemsread itr
on itr.code = bom.item_code_attr
where sor.orderid is not null
and itm.class_10 in ('A', 'D', 'M', 'S', 'Z')
从 Exact Online 检索数据。在我的测试环境中,运行 大约需要 1 秒才能在销售订单上应用 Material 爆炸清单(在 Exact Online 的 XML 和 REST API 上大约读取 5 次).但是,在客户站点上 运行 超过 15 分钟。好像和Material的Bill中使用的items(articles)的检索有关;在我的测试环境中大约有 100 个项目,而客户站点有 250.000 个项目。
但是,此查询用于交互式程序,应该 运行 在 2.5 秒内。
我试图结合 itemsread 和 items 来限制检索的项目,但是它们有不同的字段,这两个表都需要。
如何针对大量数据优化此查询以运行更快?
问题出在第二个查询中:项目很多,而 Exact Online 的 API 吞吐量可能是每秒 300 个项目。所以这一切都没有改变。
有两条备选路线:
- 优化查询
- 使用缓存
查询优化确保了在首次使用和后续使用时的出色性能和极少的资源占用。使用缓存可以缩短第二次使用的响应时间,但需要比优化查询更多的资源。
优化在线精确查询
要优化查询,您需要指示优化器如何更正确地处理连接,因为 Exact Online 默认情况下没有可用的统计信息和参考数据。我会添加以下提示:
select /*+ join_set(soe, orderid, 100) join_set(itm, id, 100) join_set(itr, code, 100) */ ...
from settings@inmemorystorage stg
...
第一个提示 join_set(soe, orderid, 100)
指示优化器将连接算法从散列连接更改为索引循环,以便在 orderid
上连接 soe
(右侧)时执行路径中上一步最多返回 100 行。在这种情况下,将从 settings
返回一行。 itm
和 itr
.
对于大型 Exact Online 环境,这将确保在销售订单行数少于 60 行时始终有 5 次查找。这通常需要 1 秒。
使用缓存(Data Cache)
当您将 PostgreSQL、SQL 服务器、Oracle 或 MySQL 数据库配置为 Invantive Data Cache 支持数据库提供程序时,您可以获得部分查询的结果存储在普通数据库中。当数据缓存仍然足够 "fresh".
时,优化器会自动使用 ANSI SQL 查询此普通数据库例如:
select /*+ ods(true, interval '7 days') */ ...
告诉优化器在不超过 7 天前将数据放入数据缓存时对所有 Exact Online 数据使用数据缓存。当超过 7 天时,它创建一个新版本,将其存储在数据缓存中并使用它。
当您需要在 Exact Online 中包含近乎实时的更改时,您将必须配置数据复制。然后它通过网络挂钩检索所有 insert/update/delete 事件并将它们应用于您的数据缓存。但是缓存可能仍然有 30 分钟的历史,因为传播可能需要一些时间。
性能比没有缓存和没有优化好很多。一般来说,250.000 个项目的吞吐量会好 1.000 倍,因此与使用 250 个项目相当。鉴于 Exact Online 的典型页面大小为 60,感觉为 5 + 5 + 3 = 13 I/Os,因此大约 2,6 秒,接近 2,5 秒的给定边界。
请注意,您正在使用的材料清单 table 将永远不会使用索引查找,因为此时没有可用的索引。因此,如果您的所有产品都有大量物料清单,则必须进行数据缓存以获得合理的性能。