每个人,最近我参与了一个针对oracle的SQL调优任务, 我认为我遇到了一个非常困难的问题,甚至可以说我对这个问题感到害怕, 我从DBA获得了AWR报告,似乎来自AMR的红线SQL需要做一些调整(我将这些SQL粘贴如下,该sql在SP中)。但是我不知道是什么原因导致性能不佳,任何人可以帮助提供一些有关调整SQL的解决方案或想法?
如果您需要AWR提供的更多证据,请告诉我。
预先感谢...
UPDATE tax_ratio tar
SET
( ecm,
esm,
epm,
ecam,
update_dt,
update_by ) = (
SELECT
nvl(src_t1.ecm,0) AS ecm,
nvl(src_t1.esm,0) AS esm,
nvl(src_t1.epm,0) AS epm,
nvl(src_t1.ecam,0) AS ecam,
SYSDATE,
'ffee_user'
FROM
(
SELECT
city_code,
tax_type,
company_type,
taxpayer,
company_group,
company_tax_type,
SUM(new_tax_current_mth) /12 AS ecm,
SUM(new_tax_miss_current_mth) /12 AS esm,
SUM(new_tax_get_current_mth) /12 AS epm,
SUM(new_tax_special_current_mth) /12 AS ecam
FROM
tax_ratio
WHERE
city_code ='001'
AND company_type ='typ_01'
AND tax_mth <= add_months(TO_DATE('08-JUL-2015'),-3)
AND tax_mth >= add_months(TO_DATE('08-JUL-2015'),-14)
AND eff_date =TO_DATE('08-JUL-2015')
AND tax_type = '00'
GROUP BY
city_code,
tax_type,
company_type,
taxpayer,
company_group,
company_tax_type
HAVING SUM(new_tax_current_mth) <> 0
OR SUM(new_tax_miss_current_mth) <> 0
OR SUM(new_tax_get_current_mth) <> 0
OR SUM(new_tax_special_current_mth) <> 0
) src_t1
WHERE
tar.city_code = src_t1.city_code
AND tar.tax_type = src_t1.tax_type
AND tar.company_type = src_t1.company_type
AND tar.taxpayer = src_t1.taxpayer
AND nvl(tar.company_group,'-99999') = nvl(src_t1.company_group,'-99999')
AND (
src_t1.ecm IS NOT NULL
OR src_t1.esm IS NOT NULL
OR src_t1.epm IS NOT NULL
OR src_t1.ecam IS NOT NULL
)
AND tar.tax_mth =TO_DATE('08-JUL-2015')
AND tar.company_tax_type = src_t1.company_tax_type
)
WHERE
tar.city_code ='001'
AND tar.company_type ='typ_01'
AND tar.tax_mth =TO_DATE('08-JUL-2015')
AND EXISTS (
SELECT
1
FROM
(
SELECT
city_code,
tax_type,
company_type,
taxpayer,
company_group,
company_tax_type,
SUM(new_tax_current_mth) /12 AS ecm,
SUM(new_tax_miss_current_mth) /12 AS esm,
SUM(new_tax_get_current_mth) /12 AS epm,
SUM(new_tax_special_current_mth) /12 AS ecam
FROM
tax_ratio
WHERE
city_code ='001'
AND company_type ='typ_01'
AND tax_mth <= add_months(TO_DATE('08-JUL-2015'),-3)
AND tax_mth >= add_months(TO_DATE('08-JUL-2015'),-14)
AND eff_date =TO_DATE('08-Aug-2015')
AND tax_type = '00'
GROUP BY
city_code,
tax_type,
company_type,
taxpayer,
company_group,
company_tax_type
HAVING SUM(new_tax_current_mth) <> 0
OR SUM(new_tax_miss_current_mth) <> 0
OR SUM(new_tax_get_current_mth) <> 0
OR SUM(new_tax_special_current_mth) <> 0
) src_t1
WHERE
tar.city_code = src_t1.city_code
AND tar.tax_type = src_t1.tax_type
AND tar.company_type = src_t1.company_type
AND tar.taxpayer = src_t1.taxpayer
AND nvl(tar.company_group,'-99999') = nvl(src_t1.company_group,'-99999')
AND (
src_t1.ecm IS NOT NULL
OR src_t1.esm IS NOT NULL
OR src_t1.epm IS NOT NULL
OR src_t1.ecam IS NOT NULL
)
AND tar.tax_mth =TO_DATE('08-JUL-2015')
AND tar.company_tax_type = src_t1.company_tax_type
)
add the EXPLAIN PLAN
PLAN HASH VALUE: 3650439649
----------------------------------------------------------------------------------------------------------------------
| ID | OPERATION | NAME | ROWS | BYTES |TEMPSPC| COST (%CPU)| TIME |
----------------------------------------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 1698 | 179K| | 6169K (1)| 00:08:02 |
| 1 | UPDATE | TAX_RATIO | | | | | |
|* 2 | HASH JOIN RIGHT SEMI | | 1698 | 179K| | 732K (1)| 00:00:58 |
| 3 | VIEW | | 39251 | 1111K| | 371K (2)| 00:00:29 |
|* 4 | FILTER | | | | | | |
| 5 | SORT GROUP BY | | 39251 | 2414K| 100M| 371K (2)| 00:00:29 |
|* 6 | TABLE ACCESS FULL | TAX_RATIO | 1140K| 68M| | 365K (2)| 00:00:29 |
|* 7 | TABLE ACCESS FULL | TAX_RATIO | 207K| 15M| | 361K (1)| 00:00:29 |
| 8 | VIEW | | 1 | 81 | | 484 (1)| 00:00:01 |
|* 9 | FILTER | | | | | | |
| 10 | SORT GROUP BY | | 1 | 63 | | 484 (1)| 00:00:01 |
|* 11 | FILTER | | | | | | |
|* 12 | TABLE ACCESS BY INDEX ROWID BATCHED| TAX_RATIO | 1 | 63 | | 483 (0)| 00:00:01 |
|* 13 | INDEX RANGE SCAN | TAX_RATIO_TAXPAYER_IDX | 544 | | | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------------
PREDICATE INFORMATION (IDENTIFIED BY OPERATION ID):
---------------------------------------------------
2 - ACCESS("TAR"."CITY_CODE"="SRC_T1"."CITY_CODE" AND "TAR"."TAX_TYPE"="SRC_T1"."TAX_TYPE" AND
"TAR"."COMPANY_TYPE"="SRC_T1"."COMPANY_TYPE" AND "TAR"."TAXPAYER"="SRC_T1"."TAXPAYER" AND
NVL("TAR"."COMPANY_GROUP",'-99999')=NVL("SRC_T1"."COMPANY_GROUP",'-99999') AND "TAR"."COMPANY_TAX_TYPE"="SRC_T1"."COMPANY_TAX_TYPE")
4 - FILTER((SUM("NEW_TAX_CURRENT_MTH")<>0 OR SUM("NEW_TAX_MISS_CURRENT_MTH")<>0 OR SUM("NEW_TAX_GET_CURRENT_MTH")<>0 OR SUM("NEW_TAX_SPECIAL_CURRENT_MTH")<>0) AND
(SUM("NEW_TAX_CURRENT_MTH")/12 IS NOT NULL OR SUM("NEW_TAX_MISS_CURRENT_MTH")/12 IS NOT NULL OR SUM("NEW_TAX_GET_CURRENT_MTH")/12 IS NOT NULL OR
SUM("NEW_TAX_SPECIAL_CURRENT_MTH")/12 IS NOT NULL))
6 - FILTER("COMPANY_TYPE"='LIMIT' AND "TAX_TYPE"='00' AND "TAX_MTH">=TO_DATE(' 2017-03-31 00:00:00',
'SYYYY-MM-DD HH24:MI:SS') AND "TAX_MTH"<=TO_DATE(' 2018-02-28 00:00:00', 'SYYYY-MM-DD HH24:MI:SS') AND
"CITY_CODE"='001' AND "NEW_TAX_MISS_CURRENT_MTH"=TO_DATE(' 2200-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'))
7 - FILTER("TAR"."TAX_MTH"=TO_DATE(' 2018-05-31 00:00:00', 'SYYYY-MM-DD HH24:MI:SS') AND
"TAR"."COMPANY_TYPE"='LIMIT' AND "TAR"."CITY_CODE"='001')
9 - FILTER((SUM("NEW_TAX_CURRENT_MTH")<>0 OR SUM("NEW_TAX_MISS_CURRENT_MTH")<>0 OR SUM("NEW_TAX_GET_CURRENT_MTH")<>0 OR SUM("NEW_TAX_SPECIAL_CURRENT_MTH")<>0) AND
(SUM("NEW_TAX_CURRENT_MTH")/12 IS NOT NULL OR SUM("NEW_TAX_MISS_CURRENT_MTH")/12 IS NOT NULL OR SUM("NEW_TAX_GET_CURRENT_MTH")/12 IS NOT NULL OR
SUM("NEW_TAX_SPECIAL_CURRENT_MTH")/12 IS NOT NULL))
11 - FILTER(:B1=TO_DATE(' 2018-05-31 00:00:00', 'SYYYY-MM-DD HH24:MI:SS') AND :B2='LIMIT' AND :B3='00' AND
:B4='001')
12 - FILTER("COMPANY_TYPE"='LIMIT' AND "COMPANY_TAX_TYPE"=:B1 AND "TAX_TYPE"='00' AND "TAX_MTH">=TO_DATE('
2017-03-31 00:00:00', 'SYYYY-MM-DD HH24:MI:SS') AND "TAX_MTH"<=TO_DATE(' 2018-02-28 00:00:00', 'SYYYY-MM-DD
HH24:MI:SS') AND NVL("COMPANY_GROUP",'-99999')=NVL(:B2,'-99999') AND "CITY_CODE"='001' AND "NEW_TAX_MISS_CURRENT_MTH"=TO_DATE('
2200-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'))
13 - ACCESS("TAXPAYER"=:B1)
答案 0 :(得分:1)
我要尝试的第一件事是使用MERGE语句而不是该UPDATE语句-这让我想到了,因为您实际上是在where子句的set子句中重复子查询。
我认为您的UPDATE可以重写为:
MERGE INTO tax_ratio tgt
USING (SELECT city_code,
tax_type,
company_type,
taxpayer,
company_group,
company_tax_type,
SUM(new_tax_current_mth) / 12 AS ecm,
SUM(new_tax_miss_current_mth) / 12 AS esm,
SUM(new_tax_get_current_mth) / 12 AS epm,
SUM(new_tax_special_current_mth) / 12 AS ecam
FROM tax_ratio
WHERE city_code = '001'
AND company_type = 'typ_01'
AND tax_mth <= add_months(to_date('08-JUL-2015', 'dd-MON-yyyy', 'nls_date_language = english'), -3)
AND tax_mth >= add_months(to_date('08-JUL-2015', 'dd-MON-yyyy', 'nls_date_language = english'), -3)
AND eff_date = to_date('08-JUL-2015', 'dd-MON-yyyy', 'nls_date_language = english')
AND tax_type = '00'
GROUP BY city_code,
tax_type,
company_type,
taxpayer,
company_group,
company_tax_type
HAVING SUM(new_tax_current_mth) <> 0
OR SUM(new_tax_miss_current_mth) <> 0
OR SUM(new_tax_get_current_mth) <> 0
OR SUM(new_tax_special_current_mth) <> 0)) src
ON (tgt.city_code = src.city_code
AND tgt.tax_type = src.tax_type
AND tgt.company_type = src.company_type
AND tgt.taxpayer = src.taxpayer
AND NVL(tgt.company_group, '-99999') = NVL(src.company_group, '-99999')
--AND COALESCE(src.ecm, src.esm, src.epm, src.ecam) IS NOT NULL -- unnecessary, since your having clause excludes rows where all are null anyway
AND tgt.company_tax_type = src.company_tax_type)
WHEN MATCHED THEN
UPDATE SET tgt.ecm = NVL(src.ecm, 0),
tgt.esm = NVL(src.esm, 0),
tgt.epm = NVL(src.epm, 0),
tgt.ecam = NVL(src.ecam, 0),
tgt.update_dt = SYSDATE,
tgt.update_by = 'ffee_user')
WHERE tgt.tax_mth = to_date('08-JUL-2015', 'dd-MON-yyyy', 'nls_date_language = english');
注意:
to_dates()
以包括格式掩码(否则,如果您的NLS_DATE_FORMAT nls参数被更改,则to_date()
将会失败),并且由于您使用“ JUL”作为月份,附加的第三个参数,以使按字符串进行日期转换nls的设置独立(例如,如果将您的NLS_DATE_FORMAT nls参数设置为JUL
不是有效的短个月,则to_date()
如果未设置此第三个参数,则失败。
您可以通过将日期作为数字传递来避免使用第三个参数,例如to_date('05/07/2015', 'dd/mm/yyyy')
。 and ecm is not null and esm is not null and ...
改为使用COALESCE
,因为这将返回列表中的第一个非空值。这样,您的支票就变成了and COALESCE(ecm, esm, ...) is not null
。我将对新的MERGE语句进行测试,以确保它在做正确的事情(或对其进行修复,直到它起作用为止),然后查看它如何影响性能。
如果它仍然作为AWR中的问题说明弹出,那么我将进一步研究如何调整它;也许需要更新/附加索引,也许需要物化视图等。