【问题标题】:Query tuning Oracle查询调优 Oracle
【发布时间】:2016-03-15 06:20:01
【问题描述】:

在执行以下查询时,运行时间超过 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');

【问题讨论】:

  • We need more informationEdit 你的问题并添加表格的定义(如create table 语句,no screen shots 请),所有定义的索引和执行计划(也作为 格式化 文本,没有屏幕截图)。

标签: sql oracle


【解决方案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_errorsatcom235 的加入。
  • 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))。因为这些是您用来访问表记录的字段。

【讨论】:

    【解决方案2】:

    1.检查您是否使用索引列连接表,同时检查连接和 检查(How to reduce query execution time for table with huge data"这可能对你有帮助)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-26
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多