0

我正在使用以下查询:

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 秒以将物料清单爆炸应用于销售订单(在 Exact Online 的 XML 和 REST API 上大约读取 5 次)。但是,在客户站点上运行时间超过 15 分钟。似乎与物料清单中使用的物品(物品)的检索有关;在我的测试环境中,大约有 100 个项目,而客户站点有 250.000 个项目。

但是,此查询用于交互式程序,应在 2.5 秒内运行。

我尝试将 itemsread 和 items 结合起来以限制检索到的项目,但是它们具有两个表都需要的不同字段。

如何优化此查询以更快地处理大量数据?

4

1 回答 1

1

问题出在第二个查询中:有很多项目,Exact Online 的 API 的吞吐量可能为每秒 300 个项目。所以这已经过去了,永远不会改变。

有两种替代路线:

  1. 优化查询
  2. 使用缓存

查询优化确保了首次和后续使用时的出色性能和极少的资源使用。缓存的使用提高了第二次使用时的响应时间,但需要比优化查询更多的资源。

优化精确在线查询

要优化查询,您需要指示优化器如何更正确地处理连接,因为 Exact Online 默认情况下没有可用的统计信息和参考数据。我会添加以下提示:

select /*+ join_set(soe, orderid, 100) join_set(itm, id, 100) join_set(itr, code, 100) */ ...
from   settings@inmemorystorage stg
...

当执行路径中的上一步返回最多 100 行时,第一个提示join_set(soe, orderid, 100)指示优化器将连接算法从散列连接更改为按索引进行的循环连接(soe右侧)。orderid在这种情况下,将恰好返回一行settings。和上的连接itm也是如此itr

对于大型 Exact Online 环境,这将确保您在销售订单少于 60 行时始终进行 5 次查找。这通常需要 1 秒。

使用缓存(数据缓存)

当您将 PostgreSQL、SQL Server、Oracle 或 MySQL 数据库配置为 Invantive Data Cache 后备数据库提供程序时,您可以将部分查询的结果存储在普通数据库中。当数据缓存仍然足够“新鲜”时,优化器会自动使用 ANSI SQL 查询这个普通数据库。

例如:

select /*+ ods(true, interval '7 days') */ ...

告诉优化器在不超过 7 天前将数据放入数据缓存中时对所有 Exact Online 数据使用数据缓存。当它超过 7 天时,它会创建一个新版本,将其存储在数据缓存中并使用它。

当您需要在 Exact Online 中包含近乎实时的更改时,您必须配置数据复制。然后它通过网络挂钩检索所有插入/更新/删除事件并将它们应用到您的数据缓存中。但是缓存可能仍然存在 30 分钟,因为传播可能需要一些时间。

性能比没有缓存和没有优化要好很多。一般来说,使用 250.000 个项目的吞吐量会好 1.000 倍,因此与使用 250 个项目相当。考虑到 Exact Online 的典型页面大小为 60,感觉就像 5 + 5 + 3 = 13 个 I/O,因此大约 2.6 秒,接近给定的 2.5 秒边界。

请注意,您使用的物料清单表永远不会使用按索引查找,因为此时没有可用的索引。因此,如果您在所有产品中都有大量物料清单,则必须进行数据缓存以获得合理的性能。

于 2017-05-22T12:48:52.387 回答