[20221012]修改統計資訊最佳化sql語句.txt
[20221012]修改統計資訊最佳化sql語句.txt
--//生產系統一類sql語句出現一點點效能問題,選擇錯誤的索引,透過修改統計資訊最佳化sql語句來最佳化sql語句.
1.環境:
SYS@192.168.100.235:1521/orcl> @ prxx
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 19.0.0.0.0
BANNER : Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
BANNER_FULL : Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
BANNER_LEGACY : Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
2.分析:
--//語句類似如下,存在兩種風格的update語句.一類包含barcode,一類沒有而是包含barcode.
UPDATE LIS_RESULT_TEMP
SET in_flag = 1, in_time = :in_time
WHERE barcode = :barcode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AND inst_id = :inst_id
AND in_flag = 0
AND write_time >= :write_time
AND Item_Channel IN ( :Item_Channel1
, :Item_Channel2
...
, :Item_Channel104
, :Item_Channel105
, :Item_Channel106)
UPDATE LIS_RESULT_TEMP
SET in_flag = 1, in_time = :in_time
WHERE test_no = :test_no
AND inst_id = :inst_id
AND test_date = :test_date
AND in_flag = 0
AND write_time >= :write_time
AND Item_Channel IN ( :Item_Channel1
, :Item_Channel2
...
, :Item_Channel49)
--//查詢建立索引如下:
SYS@192.168.100.235:1521/orcl> @ ind2 lis.LIS_RESULT_TEMP
Display indexes where table or index name matches lis.LIS_RESULT_TEMP...
TABLE_OWNER TABLE_NAME INDEX_NAME POS# COLUMN_NAME DSC
-------------------- ------------------------------ ------------------------------ ---- ------------------------------ ----
LIS LIS_RESULT_TEMP IX_LIS_RESULT_TEMP_BARCODE 1 BARCODE
IX_LIS_RESULT_TEMP_T_3 1 TEST_NO
2 TEST_DATE
3 INST_ID
IX_LIS_RESULT_TEMP_WRITE_TIME 1 WRITE_TIME
I_LIS_RESULT_TEMP_IN_FLAG 1 IN_FLAG
PK_LIS_RESULT_TEMP 1 ID
INDEX_OWNER TABLE_NAME INDEX_NAME IDXTYPE UNIQ STATUS PART TEMP H LFBLKS NDK NUM_ROWS CLUF LAST_ANALYZED DEGREE VISIBILIT
-------------------- ------------------------------ ------------------------------ ---------- ---- -------- ---- ---- -- ---------- ------------- ---------- ---------- ------------------- ------ ---------
LIS LIS_RESULT_TEMP IX_LIS_RESULT_TEMP_BARCODE NORMAL NO VALID NO N 3 12618 61224 1575217 143148 2022-10-11 22:00:25 1 VISIBLE
LIS_RESULT_TEMP IX_LIS_RESULT_TEMP_T_3 NORMAL NO VALID NO N 3 10539 19208 1820170 137855 2022-10-11 22:00:31 1 INVISIBLE
LIS_RESULT_TEMP IX_LIS_RESULT_TEMP_WRITE_TIME NORMAL NO VALID NO N 3 7361 72944 1820118 132620 2022-10-11 22:00:35 1 INVISIBLE
LIS_RESULT_TEMP I_LIS_RESULT_TEMP_IN_FLAG NORMAL NO VALID NO N 3 3245 2 1820159 35682 2022-10-11 22:00:39 1 VISIBLE
LIS_RESULT_TEMP PK_LIS_RESULT_TEMP NORMAL YES VALID NO N 3 4327 1820170 1820170 245835 2022-10-11 22:00:38 1 VISIBLE
--//注:IN_FLAG 索引是我事後建立的.
--//我發現即使一些包含欄位BARCODE的等值語句,有一些選擇barcode索引,有一些選擇write_time.
--//而沒有包含欄位BARCODE的語句,會選擇IX_LIS_RESULT_TEMP_T_3索引,有一些選擇write_time.
--//除了選擇BARCODE效果很好外,其它情況的邏輯讀都很高,達到18XX.特別到了下午晚上的情況更加嚴重,因為test_date,WRITE_TIME數
--//據隨著當前業務的累加,記錄會越來越多.
--//LIS_RESULT_TEMP 從字面可以看出是報錯結果的"臨時"表.修改後in_flag從0=>1.看看IN_FLAG的資料分佈.
SYS@192.168.100.235:1521/orcl> @ tabhist lis.LIS_RESULT_TEMP IN_flag
COLUMN_NAME DATA_TYPE HISTOGRAM SAMPLE_SIZE ENDPOINT_NUMBER ENDPOINT_VALUE FREQUENCY HEIGHT_BAL ENDPOINT_ACTUAL_VALUE
------------------------------ -------------------- --------------- ----------- --------------- ------------------------------ ---------- ---------- ----------------------------------------
IN_FLAG NUMBER FREQUENCY 1820118 15 0 15 0
FREQUENCY 1820118 1820118 1 1820103 1
--//很明顯建立IN_FLAG可能效果不錯,另外在業務高峰時,IN_FLAG的數量可以達到4XX.
--//於是我臨時設定IX_LIS_RESULT_TEMP_T_3,IX_LIS_RESULT_TEMP_WRITE_TIME 索引INVISIBLE(不可用).
--//重新整理共享池觀察,發現欄位BARCODE的等值語句,有一些選擇barcode索引,有一些選擇IN_FLAG索引.不知道是否沒有重新整理共享池的原因.
--//好像多數選擇IN_FLAG索引.我希望發現欄位BARCODE的等值語句,最好還是選擇barcode的索引.
--//一般情況下我會選擇sql profile來穩定執行計劃,但是裡面的專案數量Item_Channel會變,使用sql profile明顯不現實.
--//我突然想到應該透過修改barcode的Density來控制執行計劃:
SYS@192.168.100.235:1521/orcl> @ descz lis.LIS_RESULT_TEMP "column_name in ('IN_FLAG','BARCODE')"
eXtended describe of lis.LIS_RESULT_TEMP
DISPLAY TABLE_NAME OF COLUMN_NAME INFORMATION.
INPUT OWNER.TABLE_NAME <filters>
SAMPLE : @ TAB_LH TABLE_NAME "column_id between 3 and 5"
IF NOT INPUT <filters> ,USE "1=1" .
Owner Table_Name SAMPLE_SIZE LAST_ANALYZED Col# Column Name Null? Type NUM_DISTINCT Density NUM_NULLS HISTOGRAM NUM_BUCKETS Low_value High_value
---------- -------------------- ----------- ------------------- ---- -------------------- ---------- -------------------- ------------ -------------- ---------- --------------- ----------- ---------- ------------
LIS LIS_RESULT_TEMP 1575217 2022-10-11 22:00:11 3 BARCODE NVARCHAR2(28) 61224 .00001633346 244953 1 0150860102 _HIV Ag/AbL4
1820118 2022-10-11 22:00:11 24 IN_FLAG NUMBER(1,0) 2 .00000027471 52 FREQUENCY 2 0 1
2 rows selected.
--//這樣只要查詢包含欄位BARCODE的等值查詢,優先選擇PAT_BARCODE索引,整個執行計劃就可以很好的控制.
--//注意看Density列的值.我把barcode的Density設定低一些就ok了.
SYS@192.168.100.235:1521/orcl> exec dbms_stats.SET_COLUMN_STATS('LIS','LIS_RESULT_TEMP','BARCODE',DENSITY=>.0000001,NO_INVALIDATE=>false);
PL/SQL procedure successfully completed.
SYS@192.168.100.235:1521/orcl> @ descz lis.LIS_RESULT_TEMP "column_name in ('IN_FLAG','BARCODE')"
eXtended describe of lis.LIS_RESULT_TEMP
DISPLAY TABLE_NAME OF COLUMN_NAME INFORMATION.
INPUT OWNER.TABLE_NAME <filters>
SAMPLE : @ TAB_LH TABLE_NAME "column_id between 3 and 5"
IF NOT INPUT <filters> ,USE "1=1" .
Owner Table_Name SAMPLE_SIZE LAST_ANALYZED Col# Column Name Null? Type NUM_DISTINCT Density NUM_NULLS HISTOGRAM NUM_BUCKETS Low_value High_value
---------- -------------------- ----------- ------------------- ---- -------------------- ---------- -------------------- ------------ -------------- ---------- --------------- ----------- ---------- ------------
LIS LIS_RESULT_TEMP 1575217 2022-10-12 09:15:45 3 BARCODE NVARCHAR2(28) 61224 .00000010000 244953 1 0150860102 _HIV Ag/AbL4
1820118 2022-10-11 22:00:11 24 IN_FLAG NUMBER(1,0) 2 .00000027471 52 FREQUENCY 2 0 1
2 rows selected.
--//重新整理共享池觀察,可以發現基本實現我的最佳化目的.查詢共享池發現最大的邏輯讀13X.
3.lock表,避免以後的分析修改該表的統計資訊:
SYS@192.168.100.235:1521/orcl> exec dbms_stats.LOCK_TABLE_STATS('LIS','LIS_RESULT_TEMP');
PL/SQL procedure successfully completed.
SYS@192.168.100.235:1521/orcl> @ cs lis
alter session set current_schema=lis
Session altered.
SYS@192.168.100.235:1521/orcl> @ gts LIS_RESULT_TEMP
Gather Table Statistics for table LIS_RESULT_TEMP...
BEGIN dbms_stats.gather_table_stats(null, upper('LIS_RESULT_TEMP'), null, method_opt=>'FOR TABLE FOR ALL COLUMNS SIZE REPEAT', cascade=>true, no_invalidate=>false); END;
*
ERROR at line 1:
ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512: at "SYS.DBMS_STATS", line 40751
ORA-06512: at "SYS.DBMS_STATS", line 40035
ORA-06512: at "SYS.DBMS_STATS", line 9393
ORA-06512: at "SYS.DBMS_STATS", line 10317
ORA-06512: at "SYS.DBMS_STATS", line 39324
ORA-06512: at "SYS.DBMS_STATS", line 40183
ORA-06512: at "SYS.DBMS_STATS", line 40732
ORA-06512: at line 1
SYS@192.168.100.235:1521/orcl> @ cs sys
alter session set current_schema=sys
Session altered.
--//已經實現lock表功能.
4.觀察一段時間看看:
--//IX_LIS_RESULT_TEMP_T_3,IX_LIS_RESULT_TEMP_WRITE_TIME索引可能根本不需要.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2917890/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20221216]建立修改表統計資訊minmaxtab.sql指令碼.txtSQL指令碼
- [20221216]建立修改表統計資訊modtab.sql指令碼.txtSQL指令碼
- [20221012]完善spsw.sql指令碼.txtSQL指令碼
- 統計介面sql語句SQL
- SQL語句最佳化SQL
- 統計報表 -- sql統計語句SQL
- [20221216]建立修改表欄位統計資訊modcol.sql指令碼.txtSQL指令碼
- [20211009]使用bash計算sql語句的sql_id.txtSQL
- [20201105]再分析sql語句.txtSQL
- [20220117]超長sql語句.txtSQL
- [20201210]sql語句優化.txtSQL優化
- 資料庫最佳化技巧 - SQL語句最佳化資料庫SQL
- [20191101]通過zsh計算sql語句的sql_id.txtSQL
- [20191011]通過bash計算sql語句的sql_id.txtSQL
- [20220331]如何調整sql語句.txtSQL
- [提問交流]怎麼修改更新文件資訊的sql語句SQL
- [20240607]PL/SQL中sql語句的註解.txtSQL
- [20240320]空格與sqlpus的sql語句.txtSQL
- [20200320]SQL語句優化的困惑.txtSQL優化
- [20220111]該語句的sql_id如何計算的.txtSQL
- spark sql語句效能最佳化及執行計劃SparkSQL
- 微課sql最佳化(3)、統計資訊收集(2)-如何收集統計資訊SQL
- 微課sql最佳化(8)、統計資訊收集(6)-統計資訊查詢SQL
- 兩表聯查修改的sql語句SQL
- [20181119]sql語句執行緩慢分析.txtSQL
- [20181114]一條sql語句的優化.txtSQL優化
- [20211221]分析sql語句遇到的問題.txtSQL
- [20220329]是否開發寫錯sql語句.txtSQL
- [20210923]sql語句佔用Sharable Memory分析.txtSQL
- 【資料庫】SQL語句資料庫SQL
- [20200324]SQL語句優化的困惑2.txtSQL優化
- [20211224]vim外掛格式化sql語句.txtSQL
- [20211231]vim自動格式化sql語句.txtSQL
- [20220119]超長sql語句補充3.txtSQL
- [20220329]19c sql語句打補丁.txtSQL
- [20220120]超長sql語句補充4.txtSQL
- [20210112]ashtop查詢特定表的SQL語句.txtSQL
- MySQL 修改int型別為bigint SQL語句拼接MySql型別