查询调优Oracle

时间:2016-03-15 06:20:02

标签: sql oracle

执行以下查询时,运行时间超过45分钟。我尽量调整水平,但我没有减少时间。任何人都可以帮我减少时间。

SELECT * 
FROM dte_Errors be1
WHERE BE1.source_name = 'TOS_TABIN235_1'
  AND (be1.source_name, be1.PK_VALUE) IN (SELECT be.source_name, be.PK_VALUE
                                          FROM dte_Errors be 
                                          INNER JOIN stg_tabin235 stg235 ON substr(BE.pk_Value, 1, 9) = to_char(stg235.package_id) 
                                                                         AND substr(BE.pk_Value, -9) = stg235.departure_date
                                          INNER JOIN dte_ext_lookup lkp ON lkp.package_id = stg235.package_id
                                          INNER JOIN ATC.EX_PACK_235@TROTROREAD_COMRES atcom235 ON atcom235.ext_package_id  = substr(lkp.ext_pkg_id_with_season, 1, 49)
                                          WHERE BE.source_name = 'TOS_TABIN235_1'
                                            AND stg235.departure_date = atcom235.departure_date
                                            AND SUBSTR(atcom235.EXT_PACKAGE_ID, 2, 4) NOT IN  ('IAIL1','ICLL1','IMAL1','ITUL1')
                                            AND stg235.departure_date  BETWEEN '01-NOV-12' AND '31-OCT-16');

2 个答案:

答案 0 :(得分:1)

查询检查dte_errors记录本身或具有相同source_namepk_value的其他记录是否与其他具有特定条件的表匹配。我当然不能说这是否是查询应该做的。我认为它是,但可能你只想检查记录本身。在这种情况下,从子查询中删除dte_errors访问权限。

您访问pk_value子字符串,dte_errors只是一般日志表的结果,所以这没关系。但是,您在lkp.ext_pkg_id_with_seasonatcom235.ext_package_id的子字符串上工作似乎很奇怪。如果子字符串包含单独的信息,那么为什么它们不是单独的列?这可能已成为您问题的一部分。

对于连接标准,最好直接访问列,而不是转换。如上所述,pk_value必须使用SUBSTR进行转换,但stg235.package_id必须使用TO_CHAR进行转换吗?如果可以使用substr(BE.pk_Value,1,9)安全地转换TO_NUMBER(即保证始终仅包含数字),则应将substr(BE.pk_Value,1,9) = to_char(stg235.package_id)更改为to_number(substr(BE.pk_Value,1,9)) = stg235.package_id。如果无法安全地完成此操作,您可以使用此代码:to_number(regexp_substr(BE.pk_Value, '^\d{9}$')) = stg235.package_id

因此,您同时将dte_errorsdte_ext_lookup加入stg235.package_id而不加入stg235.package_id,将另一个加入to_char(stg235.package_id)

您对departure_date的使用似乎有点模糊。您使用stg235.departure_date between '01-NOV-12' AND '31-OCT-16'这一事实让我认为它是DATE类型的列。 (否则,这只是一个字符串比较而非意外的结果。)但是,'01-NOV-12' AND '31-OCT-16' 字符串。您的DBMS可能会将它们隐含地转换为日期,但您依赖于此处的会话设置。例如,查询会在我的系统上崩溃,因为OCT在德语中没有任何意义。请改用日期文字:DATE'2012-11-01'DATE'2016-10-31'。您还应该明确地转换to_date(substr(BE.pk_Value,-9), 'DD-MON-YY') = stg235.departure_date而不是substr(BE.pk_Value,-9) = stg235.departure_date,其中同样的事情是隐含的(再次依赖于会话设置)。

我建议使用以下索引:

  • dte_errors(source_name, pk_value)。因为这是将一个dte_errors记录链接到其他记录的方法(假设这是真正需要的)。
  • dte_errors(source_name, to_number(substr(pk_value,1,9)), to_date(substr(pk_Value,-9), 'DD-MON-YY'), pk_value)。此功能索引可以加快您与stg_tabin235
  • 的加入速度
  • stg_tabin235(package_id, departure_date)。对于dte_ext_lookupdte_errors以及atcom235
  • 的加入
  • dte_ext_lookup(package_id)。当然。
  • dte_ext_lookup(substr(ext_pkg_id_with_season,1,49))。但最好还有一个单独的列ext_package_id和索引。
  • atcom235(ext_package_id, departure_date, substr(atcom235.ext_package_id,2,4))。因为这些是您用来访问表记录的字段。

答案 1 :(得分:0)

1.检查您是否正在连接带有索引列的表,还要检查连接和 检查(How to reduce query execution time for table with huge data"这可能对您有帮助)