前言:若遇到以下場景,大概率是SQL走錯了執行計劃:
1、一條SQL在頁面上查詢特別慢,但拿到數據庫終端執行特別快
2、一條SQL在某種檢索條件下查詢特別慢,但拿到數據庫終端執行特別快此時,可以嘗試按照下述步驟進行恢復:
目錄
一、分析SQL語句中涉及到的物理表,依次收集統計信息
1、單表數據量小的表,可通過以下方式收集(針對表中所有字段收集,速度相對慢)
2、單表數據量大的表,可通過以下方式收集(針對表中單個字段收集,速度相對快)
?二、SQL語句涉及表的統計信息收集完畢后,清除當前SQL的執行計劃緩存
1、查詢指定SQL的所有執行計劃緩存(一條SQL可能會有多條執行計劃緩存,每個緩存都有一個唯一的cache_item值,逐一記錄每個cache_item值)
2、根據第一步得到的所有cache_item,清除當前SQL所有的執行計劃緩存
一、分析SQL語句中涉及到的物理表,依次收集統計信息
1、單表數據量小的表,可通過以下方式收集(針對表中所有字段收集,速度相對慢)
-- 指定表收集全表字段統計信息
call DBMS_STATS.GATHER_TABLE_STATS('模式名', '物理表名稱', NULL, 100, TRUE, 'FOR ALL COLUMNS SIZE AUTO', 64,'GLOBAL');--示例:
call DBMS_STATS.GATHER_TABLE_STATS('SYSTEM', 'ORDER_TEST', NULL, 100, TRUE, 'FOR ALL COLUMNS SIZE AUTO', 64,'GLOBAL');
2、單表數據量大的表,可通過以下方式收集(針對表中單個字段收集,速度相對快)
-- 指定字段收集統計信息
stat 100 on 物理表名(表字段名);--示例:
stat 100 on ORDER_TEST(ID);
stat 100 on ORDER_TEST(AMOUNT);
stat 100 on ORDER_TEST(DELETE_FLAG);
stat 100 on ORDER_TEST(ACCOUNTING_MONTH);
?二、SQL語句涉及表的統計信息收集完畢后,清除當前SQL的執行計劃緩存
1、查詢指定SQL的所有執行計劃緩存(一條SQL可能會有多條執行計劃緩存,每個緩存都有一個唯一的cache_item值,逐一記錄每個cache_item值)
-- 模糊查詢指定SQL的所有執行計劃緩存,獲取SQL對應的cache_item字段值
select cache_item, *
from v$cachepln
where sqlstr like '%你的SQL語句%';--示例:
select cache_item, *
from v$cachepln
where sqlstr like '%SELECT * FROM ORDER_TEST WHERE ACCOUNTING_MONTH = '2025-01'%';
2、根據第一步得到的所有cache_item,清除當前SQL所有的執行計劃緩存
-- 指定清空某條SQL的緩存(cache_item字段來源于 第一步)
call SP_CLEAR_PLAN_CACHE(cache_item);示例:
call SP_CLEAR_PLAN_CACHE(281008439485408);
特別注意:SP_CLEAR_PLAN_CACHE存儲過程執行時,若不傳cache_item,則會清除當前模式下所有SQL的執行計劃緩存,生產環境請謹慎操作。