테마
버거 본사 화면(Java)과 매장 관리 도구(C#, ODP.NET, 2022)가 같은 「매장 하루 주문 목록」 SQL을 쓴다. 본사 화면은 0.01초인데 매장 관리 도구는 0.4초쯤 걸린다. 점장들이 하루 1만 5천 번쯤 열어서 DB CPU의 상당 부분을 차지한다.
매장 관리 도구 개발자가 말했다. "다국어 때문에 문자열 파라미터는 모두 NVarchar2로 넘기라는 사내 규칙이 있어서요."
ORD 주문: 1,000,000행 · 22,422블록 · 날짜순 적재 · ORD_DT VARCHAR2(8) 하루 약 1,370건 · ORD_HMS VARCHAR2(6) · SHOP_NO VARCHAR2 'SH0001' ~ 'SH0200'(매장마다 하루 약 7건)ORD_PK (ORD_NO) · ORD_X01 (ORD_DT, ORD_HMS): CF 22,223-- 「매장 하루 주문 목록」 (두 프로그램이 같은 문자열)
SELECT ORD_NO, ORD_HMS
FROM ORD
WHERE ORD_DT = :d
AND SHOP_NO = :shop
ORDER BY ORD_HMS
// 매장 관리 도구 (C#, ODP.NET) : 사내 규칙대로 문자열은 NVarchar2
cmd.Parameters.Add(new OracleParameter("d", OracleDbType.NVarchar2) { Value = ordDt });
cmd.Parameters.Add(new OracleParameter("shop", OracleDbType.NVarchar2) { Value = shopNo });
[V$SQL — 같은 SQL_ID의 자식 둘]
CHILD PLAN_HASH EXECUTIONS BUFFER_GETS/EXEC MODULE
0 3702938145 3,240 38 JDBC Thin Client
1 1093856276 14,872 22,422 ShopManager.exe
[V$SQL_SHARED_CURSOR — Y인 칸] child 1 : BIND_MISMATCH = Y
[V$SQL_BIND_CAPTURE]
CHILD NAME DATATYPE_STRING
0 :D VARCHAR2(32)
0 :SHOP VARCHAR2(32)
1 :D NVARCHAR2(32)
1 :SHOP NVARCHAR2(32)
[자식 1 — 매장 관리 도구 한 번]
-------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
-------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 7 |00:00:00.38 | 22422 | |
| 1 | SORT ORDER BY | | 1 | 100 | 7 |00:00:00.38 | 22422 | 2048 (0)|
|* 2 | TABLE ACCESS FULL | ORD | 1 | 100 | 7 |00:00:00.38 | 22422 | |
-------------------------------------------------------------------------------------------------------------
2 - filter((SYS_OP_C2C("ORD_DT")=:D AND SYS_OP_C2C("SHOP_NO")=:SHOP))
[자식 0 — 본사 화면 한 번]
-------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
-------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 7 |00:00:00.01 | 38 | |
|* 1 | TABLE ACCESS BY INDEX ROWID| ORD | 1 | 7 | 7 |00:00:00.01 | 38 | |
|* 2 | INDEX RANGE SCAN | ORD_X01 | 1 | 1370 | 1370 |00:00:00.01 | 7 | |
-------------------------------------------------------------------------------------------------------------
1 - filter("SHOP_NO"=:SHOP)
2 - access("ORD_DT"=:D)