原文地址:https://www.soughttech.com/front/article/7159/viewArticle 今天我偶然看到了參數slave_exec_mode。從手冊中的描述可以看出,該參數與MySQL複製有關。它是一個可以動態修改的變數。預設為STRICT mode(嚴格模式), ...
[20231207]開發不應該這樣寫sql4.txt
--//最近在優化sql語句,發現另外一種風格,實際上以前也遇到過,感覺這就像一種病,會傳染只要一個這樣寫後面的要麼跟進要麼
--//不改。我覺得開發應該感謝exadata,不然我們的生產系統估計會垮掉。
1.環境:
XXXXXX> @ver1
PORT_STRING VERSION BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
2.問題語句:
XXXXXX> @ sql_id ag76s7zum6z3b
--SQL_ID = ag76s7zum6z3b
SELECT MZ.BRID AS PATIENT_ID,
TO_CHAR(GH.SBXH) AS OUTPATIENT_ID,
:"SYS_B_0" AS INHOSPITAL_ID, JZLS.JZXH AS VISIT_ID, MZ.MZHM AS CARD_NO,
GH.GHSJ AS VISIT_TIME, MZ.BRXM AS PATIENT_NAME, MZ.BRXB AS PATIENT_SEX,
MZ.CSNY AS PATIENT_BIRTHDATE, MZ.SFZH AS IDENTITY_CARD_ID,
:"SYS_B_1" AS PATIENT_TYPE,
(SELECT GY_DMZD.DMMC FROM XXXXXX_YYY.GY_DMZD WHERE GY_DMZD.DMLB = :"SYS_B_2" AND GY_DMZD.DMSB = MZ.MZDM) AS PATIENT_NATION,
(SELECT GY_SSXWH.NAME FROM XXXXXX_YYY.GY_SSXWH WHERE GY_SSXWH.SBXH = MZ.XZZ_SQS) AS FAMILY_ADDRESS_PROVINCE,
(SELECT GY_SSXWH.NAME FROM XXXXXX_YYY.GY_SSXWH WHERE GY_SSXWH.SBXH = MZ.XZZ_S) AS FAMILY_ADDRESS_CITY,
MZ.LXDZ AS FAMILY_ADDRESS_DETAIL, MZ.LXDH AS MOBILE_PHONE,
GY.KSDM AS DEPART_CODE, GY.KSMC AS DEPART_NAME,
KS.KSDM AS SUB_DEPART_CODE, KS.KSMC AS SUB_DEPART_NAME,
(SELECT CSZ FROM GY_XTCS WHERE CSMC = :"SYS_B_3") AS HOS_ID
FROM XXXXXX_YYY.MS_BRDA MZ
LEFT JOIN XXXXXX_YYY.MS_GHMX GH
ON MZ.BRID = GH.BRID
LEFT JOIN XXXXXX_YYY.MS_GHKS KS
ON GH.KSDM = KS.KSDM
LEFT JOIN XXXXXX_YYY.GY_KSDM GY
ON KS.MZKS = GY.KSDM
LEFT JOIN XXXXXX_YYY.YS_MZ_JZLS JZLS
ON JZLS.GHXH = GH.SBXH
WHERE ((:card_no = :"SYS_B_4" OR :card_no IS NULL) OR MZ.MZHM = :card_no)
AND ((:patient_id = :"SYS_B_5" OR :patient_id IS NULL) OR MZ.BRID = :patient_id)
AND ((:patientName = :"SYS_B_6" OR :patientName IS NULL) OR MZ.BRXM = :patientName)
AND ((:patientSex = :"SYS_B_7" OR :patientSex IS NULL) OR MZ.BRXB = :patientSex)
AND ((:deptName = :"SYS_B_8" OR :deptName IS NULL) OR GY.KSMC = :deptName);
--//我做了格式化處理,原始程式代碼就一行。
--//可以看出開發的本意,就是帶入任意參數都可以查詢。可惜oracle 優化器沒有這麼智能,無法選擇合理的執行路徑。
--//根據輸入選擇合適的索引,導致選擇全部掃描。
[email protected]:1621/dbcn/dbcn1> @ seg2 %.MS_BRDA
SEG_MB OWNER SEGMENT_NAME SEGMENT_TYPE SEG_TABLESPACE_NAME BLOCKS HDRFIL HDRBLK
---------- -------------------- ------------------------------ -------------------- ------------------------------ ---------- ---------- ----------
1656 XXXXXX_YYY MS_BRDA TABLE XXXXXX_YYY 211968 52 852001
--//1.6G.
--//執行計劃如下:
Plan hash value: 1015797529
----------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time | OMem | 1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 60543 (100)| | | | |
| 1 | TABLE ACCESS BY INDEX ROWID | GY_DMZD | 1 | 20 | 2 (0)| 00:00:01 | | | |
|* 2 | INDEX UNIQUE SCAN | PK_GY_DMZD | 1 | | 1 (0)| 00:00:01 | 1025K| 1025K| |
| 3 | TABLE ACCESS BY INDEX ROWID | GY_SSXWH | 1 | 13 | 2 (0)| 00:00:01 | | | |
|* 4 | INDEX UNIQUE SCAN | PK_GY_SSXWH | 1 | | 1 (0)| 00:00:01 | 1025K| 1025K| |
| 5 | TABLE ACCESS BY INDEX ROWID | GY_SSXWH | 1 | 13 | 2 (0)| 00:00:01 | | | |
|* 6 | INDEX UNIQUE SCAN | PK_GY_SSXWH | 1 | | 1 (0)| 00:00:01 | 1025K| 1025K| |
| 7 | TABLE ACCESS BY INDEX ROWID | GY_XTCS | 1 | 18 | 2 (0)| 00:00:01 | | | |
|* 8 | INDEX UNIQUE SCAN | PK_GY_XTCS | 1 | | 1 (0)| 00:00:01 | 1025K| 1025K| |
| 9 | NESTED LOOPS OUTER | | 805 | 123K| 60543 (1)| 00:12:07 | | | |
|* 10 | FILTER | | | | | | | | |
|* 11 | HASH JOIN RIGHT OUTER | | 687 | 99615 | 58034 (1)| 00:11:37 | 2782K| 2782K| 1588K (0)|
| 12 | TABLE ACCESS STORAGE FULL | GY_KSDM | 1099 | 24178 | 7 (0)| 00:00:01 | 1025K| 1025K| |
|* 13 | HASH JOIN RIGHT OUTER | | 687 | 84501 | 58027 (1)| 00:11:37 | 2596K| 2596K| 1573K (0)|
| 14 | TABLE ACCESS STORAGE FULL | MS_GHKS | 429 | 11583 | 5 (0)| 00:00:01 | 1025K| 1025K| |
| 15 | NESTED LOOPS OUTER | | 687 | 65952 | 58022 (1)| 00:11:37 | | | |
|* 16 | TABLE ACCESS STORAGE FULL | MS_BRDA | 92 | 6532 | 57498 (1)| 00:11:30 | 1025K| 1025K| |
| 17 | TABLE ACCESS BY INDEX ROWID| MS_GHMX | 8 | 200 | 10 (0)| 00:00:01 | | | |
|* 18 | INDEX RANGE SCAN | IDX_MS_GHMX_BRID | 8 | | 2 (0)| 00:00:01 | 1025K| 1025K| |
| 19 | TABLE ACCESS BY INDEX ROWID | YS_MZ_JZLS | 1 | 12 | 4 (0)| 00:00:01 | | | |
|* 20 | INDEX RANGE SCAN | I_YS_MZ_JZLS_GHXH | 1 | | 2 (0)| 00:00:01 | 1025K| 1025K| |
----------------------------------------------------------------------------------------------------------------------------------
[email protected]:1621/dbcn/dbcn1> @ bind_cap ag76s7zum6z3b :card_no
SQL_ID CHILD_NUMBER WAS NAME POSITION MAX_LENGTH LAST_CAPTURED DATATYPE_STRING VALUE_STRING
------------- ------------ --- --------- -------- ---------- ------------------- --------------- ------------
ag76s7zum6z3b 0 YES :CARD_NO 5 32 2023-12-06 09:54:09 VARCHAR2(32) 90377195
1 YES :CARD_NO 5 32 2023-12-05 11:29:35 VARCHAR2(32) 02666713
2 YES :CARD_NO 5 32 2023-12-06 19:33:57 VARCHAR2(32) 91544379
[email protected]:1621/dbcn/dbcn1> @ bind_cap_awr ag76s7zum6z3b ''
no rows selected
--//這樣語句在awr歷史表還沒有記錄。可以發現在共用池抓到的sql語句都是帶入card_no參數的。
--//我多次提過不要這樣寫sql語句,這不是在學校寫家庭作業,這是生產系統!!這類語句在生產系統還有一大堆,真不知道現在的畢業生
--//如何畢業的。