我目前在基于OFBiz的ERP部署工作 正在使用的数据库是Oracle 10g企业

一个最大的问题是一些Oracle的性能问题,分析ofbiz的日志,下面的查询:

SELECT DISTINCT ORDER_ID, ORDER_TYPE_ID, ORDER_NAME, EXTERNAL_ID,
 SALES_CHANNEL_ENUM_ID, ORDER_DATE, ENTRY_DATE, VISIT_ID, STATUS_ID, CREATED_BY, 
 FIRST_ATTEMPT_ORDER_ID, CURRENCY_UOM, SYNC_STATUS_ID, BILLING_ACCOUNT_ID, 
 ORIGIN_FACILITY_ID, WEB_SITE_ID, PRODUCT_STORE_ID, TERMINAL_ID, TRANSACTION_ID, 
 AUTO_ORDER_SHOPPING_LIST_ID, NEEDS_INVENTORY_ISSUANCE, IS_RUSH_ORDER, INTERNAL_CODE, 
 REMAINING_SUB_TOTAL, GRAND_TOTAL, LAST_UPDATED_STAMP, LAST_UPDATED_TX_STAMP, CREATED_STAMP, 
CREATED_TX_STAMP, RECIBIR_BODEGAL, RECEPCIONADA_BODEGAL, FECHA_RECEPCION_BODEGAL FROM 
ERP.ORDER_HEADER WHERE ((STATUS_ID = :v0 OR STATUS_ID = :v1 OR STATUS_ID = :v2) AND 
(ORDER_TYPE_ID = :v3)) ORDER BY ORDER_DATE DESC

是很慢的。我们测试执行,而不DISTINCT查询,大约需要30秒。还有在表4.000.000+寄存器。 有指数为PK字段订单ID和几乎所有其他字段

与DISTINCT解释计划是:

SELECT STATEMENT () (null)
 SORT (ORDER BY)    (null)
  HASH (UNIQUE) (null)
   TABLE ACCESS (FULL)  ORDER_HEADER

和无DISTINCT是:

SELECT STATEMENT () (null)
 SORT (ORDER BY)    (null)
  TABLE ACCESS (FULL)   ORDER_HEADER

有关调整Oracle任何想法,以改善这种查询的性能? 这是非常困难的重写查询,因为被ofbiz的自动生成 所以我认为该解决方案是关于调整Oracle

由于事先

编辑:我使用TKPROF分析该查询,通过罗布面包车Wijk和haffax的建议,并且结果是以下

********************************************************************************

SELECT DISTINCT ORDER_ID, ORDER_TYPE_ID, ORDER_NAME, EXTERNAL_ID,
 SALES_CHANNEL_ENUM_ID, ORDER_DATE, ENTRY_DATE, VISIT_ID, STATUS_ID, CREATED_BY, 
 FIRST_ATTEMPT_ORDER_ID, CURRENCY_UOM, SYNC_STATUS_ID, BILLING_ACCOUNT_ID, 
 ORIGIN_FACILITY_ID, WEB_SITE_ID, PRODUCT_STORE_ID, TERMINAL_ID, TRANSACTION_ID, 
 AUTO_ORDER_SHOPPING_LIST_ID, NEEDS_INVENTORY_ISSUANCE, IS_RUSH_ORDER, INTERNAL_CODE, 
 REMAINING_SUB_TOTAL, GRAND_TOTAL, LAST_UPDATED_STAMP, LAST_UPDATED_TX_STAMP, CREATED_STAMP, 
CREATED_TX_STAMP, RECIBIR_BODEGAL, RECEPCIONADA_BODEGAL, FECHA_RECEPCION_BODEGAL FROM 
ERP.ORDER_HEADER WHERE STATUS_ID = 'ORDER_COMPLETED' ORDER BY ORDER_DATE DESC

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.03       0.01          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      9.10     160.81      66729      65203         37          50
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      9.14     160.83      66729      65203         37          50

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 58  

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       1        0.00          0.00
  db file scattered read                       8178        0.28        146.55
  direct path write temp                       2200        0.04          4.22
  direct path read temp                          36        0.14          2.01
  SQL*Net more data to client                     3        0.00          0.00
  SQL*Net message from client                     1        3.36          3.36
********************************************************************************

如此看来问题是“散读取数据库文件”,任何想法如何优化Oracle为了减少此事件中的等待?

与新TKPROF结果随访,此时关闭会话:

********************************************************************************

SELECT DISTINCT ORDER_ID, ORDER_TYPE_ID, ORDER_NAME, EXTERNAL_ID,
 SALES_CHANNEL_ENUM_ID, ORDER_DATE, ENTRY_DATE, VISIT_ID, STATUS_ID, CREATED_BY,
 FIRST_ATTEMPT_ORDER_ID, CURRENCY_UOM, SYNC_STATUS_ID, BILLING_ACCOUNT_ID,
 ORIGIN_FACILITY_ID, WEB_SITE_ID, PRODUCT_STORE_ID, TERMINAL_ID, TRANSACTION_ID,
 AUTO_ORDER_SHOPPING_LIST_ID, NEEDS_INVENTORY_ISSUANCE, IS_RUSH_ORDER, INTERNAL_CODE,
 REMAINING_SUB_TOTAL, GRAND_TOTAL, LAST_UPDATED_STAMP, LAST_UPDATED_TX_STAMP, CREATED_STAMP,
CREATED_TX_STAMP, RECIBIR_BODEGAL, RECEPCIONADA_BODEGAL, FECHA_RECEPCION_BODEGAL FROM
ERP.ORDER_HEADER WHERE STATUS_ID = 'ORDER_COMPLETED' ORDER BY ORDER_DATE DESC

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.03       0.01          0          0          0           0
Execute      2      0.00       0.00          0          0          0           0
Fetch        1      8.23      47.66      66576      65203         31          50
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      8.26      47.68      66576      65203         31          50

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 58 

Rows     Row Source Operation
-------  ---------------------------------------------------
     50  SORT ORDER BY (cr=65203 pr=66576 pw=75025 time=47666679 us)
3456659   TABLE ACCESS FULL ORDER_HEADER (cr=65203 pr=65188 pw=0 time=20757300 us)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       1        0.00          0.00
  db file scattered read                       8179        0.14         34.96
  direct path write temp                       2230        0.00          3.91
  direct path read temp                          52        0.14          0.84
  SQL*Net more data to client                     3        0.00          0.00
  SQL*Net message from client                     1     1510.62       1510.62
********************************************************************************
有帮助吗?

解决方案

如果这两个查询之间的差异是显着的,这将是令人惊讶的。你提到,如果没有DISTINCT查询需要大约30秒。多少时间与DISTINCT查询时间?

你能显示查询的TKPROF输出与DISTINCT,你被曝用“改变会话组事件‘10046跟踪名字永远背景下,8级’”,并断开查询已完成后,在会议结束后?这样我们就可以看到时间的实际花费,如果它是在等待什么(“直接路径读取温度”也许?)

此致 罗布。


跟进,所述TKPROF文件发布后:

我看你设法让TKPROF输出,可惜你没有创建TKPROF文件之前断开的会话。现在,光标保持开放,并没有写STAT#线到您的跟踪文件。这就是为什么你没有在你的TKPROF文件中的计划/行源工作。这将是很好,如果你可以重复此过程,若跌破该建议被证明是垃圾。

从我身边一点点炒作:我认为DISTINCT几乎无操作,因为你选择这么多列。如果这是真的,那么你的谓词“WHERE STATUS_ID =‘ORDER_COMPLETED’”是非常有选择性的,你将不必在此列索引中受益。在创建索引之后,请确保你分析得当,甚至与如果数据值是偏斜的直方图。最终的结果将是该查询一个不同的计划,从索引范围扫描,随后是:表存取BY ROWID,导致非常快速的查询。

您已经创建了一个索引之后,可以有表重新分析,包括使用该语句的直方图:

EXEC dbms_stats.gather_table_stats([所有者],[表名],级联=>真,了method_opt = 'FOR ALL索引列SIZE'>)

此致 罗布。

其他提示

既然你订购根据order_date重要的是,你必须在该字段降序索引结果。 还告诉您要使用该索引Oracle。第一放置order_date字段在查询和使用像一个提示

SELECT /*+ index(HEADERS IDX_ORDER_DATE_DESC) */ ... 
FROM ERP.ORDER_HEADER HEADERS
WHERE ...
ORDER BY ORDER_DATE DESC

这是不是这么多有指标,而是关于告诉Oracle使用它们。甲骨文是关于指数非常挑剔。你得到最佳的效果,当你根据你的最重要的查询选择指标。如有疑问,请跟踪查询。这样,您就可以在查询Oracle的哪一部分看到花费最多时间和你的指数是否真的回升与否。战斗性能问题时跟踪是非常宝贵的。

时ORDER_ID声明为使用PRIMARY KEY约束的PK?因为如果是我期望优化器认识到DISTINCT在此查询多余和优化它。如果没有约束,也不会知道它是多余的,所以会花费在“移除重复”的结果,不必要的和相当大的努力。

尝试禁用散列聚合:

select /*+ no_use_hash_aggregation*/ distinct ...

http://oracle-randolf.blogspot.com/2011/ 01 /散列aggregation.html

当故障排除,我没有SQL我发现DBMS_SQLTUNE封装节省了大量的时间的控制应用。请参见 http://download.oracle.com/docs /cd/B28359_01/appdev.111/b28419/d_sqltun.htm ,是的,不幸的是,你应该许可使用它。

有此包到运行针对在共享池中或AWR储存库中的特定SQL_ID调谐分析程序。分析将包含索引建议,如果有要通过附加的索引进行任何改进。更重要的是,分析可能会发现,它可以与甲骨文调用SQL配置文件实施的改进访问路径 - 这是一组将被保存,无论何时执行该SQL_ID使用的提示。出现这种情况,而不需要在SQL语句中要编码的提示,并有也是一种选择做什么,如果你的应用程序中声明,而不是绑定变量产生文本值,你能想到的模糊匹配的。

当然,这个工具不应该是理解应用程序的替代品,它的数据结构,但通过详细介绍一个更好的计划(如果找到)的执行路径输出读书可以教育。

甲骨文每次运行查询(TABLE ACCESS(FULL))时间访问整个表。 在STATUS_ID和ORDER_TYPE_ID列创建索引

CREATE INDEX ERP.ORDER_HEADER_I1 ON ERP.ORDER_HEADER ( STATUS_ID, ORDER_TYPE_ID );

将有很大的帮助,特别是如果有在ORDER_HEADER表STATUS_ID和ORDER_TYPE_ID的几个不同的值。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top