优化SQL,起码需要看到瓶颈, 针对瓶颈做对应的措施。今天帮同事优化SQL,insert 跑不动,我当时心里一想insert 被阻塞了?
于是心中想起insert 被阻塞的情况, insert 共享行排他锁, 和这个冲突多种情况, 比如 表中有主键,唯一索引等, insert 一条数据不提交, 其他session insert 数据就被阻塞。 当然这个还有其他情况, 我也遇到过几种,以后慢慢写出来吧。
SQl发来原来是insert select 那种, 简单交流发现 就是select 慢导致的 insert慢, 这个情况反映失真呐...
执行计划:
Execution Plan
----------------------------------------------------------
Plan hash value: 3097008152
-----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 501 | 100K| | 62987 (1)| 00:12:36 |
| 1 | NESTED LOOPS | | 501 | 100K| | 62987 (1)| 00:12:36 |
|* 2 | HASH JOIN | | 501 | 98K| | 62986 (1)| 00:12:36 |
|* 3 | TABLE ACCESS BY INDEX ROWID | IN_ADVICE | 1 | 123 | | 9 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | 10 | 1780 | | 56723 (1)| 00:11:21 |
| 5 | NESTED LOOPS | | 5809 | 312K| | 2927 (12)| 00:00:36 |
| 6 | INDEX FAST FULL SCAN | PK_MAIN_MR_BASEINFO | 442K| 4318K| | 383 (2)| 00:00:05 |
|* 7 | TABLE ACCESS BY INDEX ROWID | IN_PATIENT | 1 | 45 | | 1 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | MRID_PATIENT | 2 | | | 1 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | IN_ADVICE_001 | 81 | | | 1 (0)| 00:00:01 |
| 10 | VIEW | VIEW_MEDICINE_JIBEN_TABLE | 47460 | 1065K| | 6262 (2)| 00:01:16 |
| 11 | HASH UNIQUE | | 47460 | 2085K| 5592K| 6262 (2)| 00:01:16 |
| 12 | VIEW | VIEW_HT_MEDICINE | 47460 | 2085K| | 5717 (2)| 00:01:09 |
| 13 | SORT UNIQUE | | 47460 | 15M| 32M| 5717 (55)| 00:01:09 |
| 14 | UNION-ALL | | | | | | |
|* 15 | HASH JOIN | | 26943 | 9051K| | 618 (3)| 00:00:08 |
|* 16 | TABLE ACCESS FULL | D401 | 23912 | 793K| | 133 (4)| 00:00:02 |
|* 17 | HASH JOIN | | 7928 | 2400K| | 485 (2)| 00:00:06 |
|* 18 | HASH JOIN | | 7448 | 1745K| | 318 (2)| 00:00:04 |
| 19 | TABLE ACCESS FULL | D503 | 6646 | 590K| | 67 (2)| 00:00:01 |
|* 20 | HASH JOIN OUTER | | 7448 | 1083K| | 250 (2)| 00:00:03 |
| 21 | TABLE ACCESS FULL | D504 | 7448 | 712K| | 101 (2)| 00:00:02 |
| 22 | TABLE ACCESS FULL | M_MEDICINE_CATALOG | 16363 | 814K| | 148 (1)| 00:00:02 |
|* 23 | TABLE ACCESS FULL | D601 | 32527 | 2223K| | 166 (2)| 00:00:02 |
|* 24 | HASH JOIN | | 3887 | 1203K| | 618 (3)| 00:00:08 |
|* 25 | HASH JOIN | | 1144 | 316K| | 484 (2)| 00:00:06 |
|* 26 | HASH JOIN | | 1074 | 223K| | 317 (2)| 00:00:04 |
|* 27 | HASH JOIN | | 1073 | 169K| | 168 (2)| 00:00:03 |
|* 28 | TABLE ACCESS FULL | D504 | 1073 | 76183 | | 101 (2)| 00:00:02 |
| 29 | TABLE ACCESS FULL | D503 | 6646 | 590K| | 67 (2)| 00:00:01 |
| 30 | TABLE ACCESS FULL | M_MEDICINE_CATALOG | 16363 | 814K| | 148 (1)| 00:00:02 |
|* 31 | TABLE ACCESS FULL | D601 | 32527 | 2223K| | 166 (2)| 00:00:02 |
|* 32 | TABLE ACCESS FULL | D401 | 23912 | 793K| | 133 (4)| 00:00:02 |
|* 33 | HASH JOIN | | 7950 | 2546K| | 494 (3)| 00:00:06 |
|* 34 | HASH JOIN | | 2339 | 671K| | 360 (2)| 00:00:05 |
|* 35 | HASH JOIN | | 2345 | 464K| | 293 (2)| 00:00:04 |
|* 36 | HASH JOIN | | 2345 | 311K| | 191 (2)| 00:00:03 |
| 37 | TABLE ACCESS BY INDEX ROWID | D601 | 2481 | 205K| | 42 (0)| 00:00:01 |
|* 38 | INDEX RANGE SCAN | D601_BIE_MING_ID | 2481 | | | 2 (0)| 00:00:01 |
| 39 | TABLE ACCESS FULL | M_MEDICINE_CATALOG | 16363 | 814K| | 148 (1)| 00:00:02 |
| 40 | TABLE ACCESS FULL | D504 | 7448 | 487K| | 101 (2)| 00:00:02 |
| 41 | TABLE ACCESS FULL | D503 | 6646 | 590K| | 67 (2)| 00:00:01 |
|* 42 | TABLE ACCESS FULL | D401 | 23912 | 793K| | 133 (4)| 00:00:02 |
|* 43 | HASH JOIN | | 8680 | 2729K| | 568 (2)| 00:00:07 |
|* 44 | HASH JOIN | | 2554 | 718K| | 435 (2)| 00:00:06 |
|* 45 | HASH JOIN | | 2561 | 492K| | 367 (2)| 00:00:05 |
| 46 | TABLE ACCESS FULL | D504 | 7448 | 487K| | 101 (2)| 00:00:02 |
|* 47 | HASH JOIN | | 10933 | 1387K| | 266 (2)| 00:00:04 |
| 48 | NESTED LOOPS | | 357 | 21420 | | 99 (0)| 00:00:02 |
|* 49 | TABLE ACCESS FULL | D505 | 359 | 3231 | | 9 (0)| 00:00:01 |
| 50 | TABLE ACCESS BY INDEX ROWID| M_MEDICINE_CATALOG | 1 | 51 | | 1 (0)| 00:00:01 |
|* 51 | INDEX UNIQUE SCAN | M_MEDICINE_CATALOG_PKEY | 1 | | | 1 (0)| 00:00:01 |
| 52 | TABLE ACCESS FULL | D601 | 35008 | 2393K| | 166 (2)| 00:00:02 |
| 53 | TABLE ACCESS FULL | D503 | 6646 | 590K| | 67 (2)| 00:00:01 |
|* 54 | TABLE ACCESS FULL | D401 | 23912 | 793K| | 133 (4)| 00:00:02 |
|* 55 | INDEX UNIQUE SCAN | D510_PKEY | 1 | 5 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("C"."ADVICE_CODE"=SYS_OP_C2C("D"."MEDICINE_CODE"))
3 - filter("C"."D2_TIME">=U'20180729000000' AND "C"."ADVICE_CODE" IS NOT NULL AND ("C"."ADVICE_STATUS"=U'NC' OR
"C"."ADVICE_STATUS"=U'ND' OR "C"."ADVICE_STATUS"=U'NE' OR "C"."ADVICE_STATUS"=U'NG') AND "C"."D2_TIME" IS NOT NULL
AND "C"."D2_TIME"<=U'20180730235959')
7 - filter(LENGTH("A"."IN_PATIENT_FLOW")=10 AND "A"."AREA_NAME" IS NOT NULL)
8 - access("A"."MR_ID"="B"."MR_ID")
9 - access("A"."IN_PATIENT_FLOW"="C"."IN_PATIENT_FLOW")
15 - access("D401"."YAO_PIN_BM"="D504"."YAO_PIN_BM")
16 - filter("D401"."KU_FANG_BM"<>'XYK' AND "D401"."KU_FANG_BM"<>'ZYK' AND "D401"."KU_FANG_BM"<>'KLF' AND
"D401"."KU_FANG_BM"<>'ZJK')
17 - access("D601"."FYXMBM"="D504"."FYXMBM")
18 - access("D504"."GUI_GE_BIAN_MA"="D503"."GUI_GE_BIAN_MA")
20 - access("D504"."YI_BAO_BM"="M_MEDICINE_CATALOG"."SUBJECT_CODE"(+))
23 - filter("D601"."BIE_MING_ID"=0)
24 - access("D401"."YAO_PIN_BM"="D504"."YAO_PIN_BM")
25 - access("D601"."FYXMBM"="D504"."FYXMBM")
26 - access("D504"."YI_BAO_BM1"="M_MEDICINE_CATALOG"."SUBJECT_CODE")
27 - access("D504"."GUI_GE_BIAN_MA"="D503"."GUI_GE_BIAN_MA")
28 - filter("D504"."YI_BAO_BM1" IS NOT NULL)
31 - filter("D601"."BIE_MING_ID"=0)
32 - filter("D401"."KU_FANG_BM"<>'XYK' AND "D401"."KU_FANG_BM"<>'ZYK' AND "D401"."KU_FANG_BM"<>'KLF' AND
"D401"."KU_FANG_BM"<>'ZJK')
33 - access("D401"."YAO_PIN_BM"="D504"."YAO_PIN_BM")
34 - access("D504"."GUI_GE_BIAN_MA"="D503"."GUI_GE_BIAN_MA")
35 - access("D601"."FYXMBM"="D504"."FYXMBM")
36 - access("D601"."YI_BAO_BM"="M_MEDICINE_CATALOG"."SUBJECT_CODE")
38 - access("D601"."BIE_MING_ID">0)
42 - filter("D401"."KU_FANG_BM"<>'XYK' AND "D401"."KU_FANG_BM"<>'ZYK' AND "D401"."KU_FANG_BM"<>'KLF' AND
"D401"."KU_FANG_BM"<>'ZJK')
43 - access("D401"."YAO_PIN_BM"="D504"."YAO_PIN_BM")
44 - access("D504"."GUI_GE_BIAN_MA"="D503"."GUI_GE_BIAN_MA")
45 - access("D601"."FYXMBM"="D504"."FYXMBM")
47 - access("D601"."BIE_MING_ID"="D505"."BIE_MING_ID")
49 - filter("D505"."YI_BAO_BM1" IS NOT NULL)
51 - access("D505"."YI_BAO_BM1"="M_MEDICINE_CATALOG"."SUBJECT_CODE")
54 - filter("D401"."KU_FANG_BM"<>'XYK' AND "D401"."KU_FANG_BM"<>'ZYK' AND "D401"."KU_FANG_BM"<>'KLF' AND
"D401"."KU_FANG_BM"<>'ZJK')
55 - access("D"."MEDICINE_FL_CODE"="FEN_LEI_MA")
有兴趣的慢慢看吧, 反正我这边扫了几眼
这边肯定有问题nest_loop 关联。结合SQL,让
select count(1) from cistest.IN_ADVICE C
where C.D2_Time between '20180729000000' and '20180730235959'
and C.advice_status in ('ND', 'NC', 'NE', 'NG')
and C.ADVICE_CODE is not null
and C.D2_TIME is not null;
很慢20分钟, 这时我知道元凶了。。。于是建议建索引 IN_ADVICE (D2_Time )。 他说存储了5年数据,取一天数据,
建一个索引完事。 另外这个表20G, 建索引需要技巧。
session 级别设置 多快读128 , 并且建索引, 然后关闭索引并行特性。
建好索引 也就5S。
这边需要提出 需要做数据归档。 建索引是第二种方案。
这种SQL应该做到看一眼,就知道怎么优化,