执行以下查询时,运行时间超过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');
答案 0 :(得分:1)
查询检查dte_errors
记录本身或具有相同source_name
和pk_value
的其他记录是否与其他具有特定条件的表匹配。我当然不能说这是否是查询应该做的。我认为它是,但可能你只想检查记录本身。在这种情况下,从子查询中删除dte_errors
访问权限。
您访问pk_value
子字符串,dte_errors
只是一般日志表的结果,所以这没关系。但是,您在lkp.ext_pkg_id_with_season
和atcom235.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_errors
和dte_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_lookup
和dte_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"这可能对您有帮助)