Oracle資料傾斜導致的問題-無繫結變數
Oracle 資料傾斜導致的問題 - 無繫結變數
參考整理---<< 恩墨年貨 -SQL 與效能優化 >>
資料傾斜即表中某個欄位值不均勻,那麼什麼叫欄位值不均勻呢?
如下t1 表的 object_id 欄位值就是嚴重的欄位值不均勻, t1 表有 290020 條資料,其中 object_id 值 1 到 9 每個值只有一條記錄, object_id=10 的值有 290011 條資料。
SQL> select object_id,count(1) from t1 group by object_id order by 1;
在這種情況下,當以object_id 欄位為過濾條件時,在某些場景下可能會出現效能問題。
場景一:未使用繫結變數
1 建立測試資料
SQL> select banner_full from v$version;
BANNER_FULL
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 CJCPDB READ WRITE NO
SQL> conn cjc/cjc@cjcpdb
Connected
新建測試表 t1 :
SQL> create table t1 as select * from dba_objects;
建立索引:
SQL> create index idx_t1_01 on t1(object_id);
增加資料:
SQL> insert into t1 select * from t1;
/
SQL> update t1 set object_id=rownum;
更新資料, 使用資料分佈不均勻:
SQL> update t1 set object_id=10 where object_id>10;
290010 rows updated.
SQL> commit;
Commit complete.
SQL> select object_id,count(1) from t1 group by object_id order by 1;
當資料分佈不均勻的欄位做為過濾條件或連線條件時,如果據分佈不均勻的欄位沒有收集直方圖可能會有問題,在沒有收集直方圖的情況下,這個欄位的過濾性 DENSITY 都是等於 1/NUM_DISTINCT;
2 對測試表 t1 進行統計資訊收集
收集時指定不收集欄位object_id 的直方圖:
begin
dbms_stats.gather_table_stats ( 'CJC' ,
'T1' ,
method_opt => 'for columns object_id size 1' ,
cascade => true );
end ;
3 檢視 T1 表上 Object_id 列沒有收集直方圖資訊
select table_name ,
column_name ,
histogram ,
num_distinct ,
density ,
last_analyzed
from user_tab_col_statistics
where table_name = 'T1'
and column_name = 'OBJECT_ID' ;
4 以 object_id 列為過濾條件,對比結果集相差懸殊的兩次查詢操作的執行計劃
(1) 檢視結果集少的執行計劃
object_id=1 時結果集只有1 條資料
SQL> set autotrace traceonly
SQL> set linesize 200
SQL> set timing on
SQL> select * from t1 where object_id=1;
(2) 檢視結果集多的執行計劃
object_id=1 0 時結果集有 290011 條資料
SQL> select * from t1 where object_id=10;
290011 rows selected.
從上圖可以看出,兩條 SQL 的 PLAN_HASH_VALUE 是一樣的,走了相同的執行計劃。
select sql_text, sql_id, plan_hash_value
from v$sql
where sql_text like 'select * from t1 where object_id%';
SELECT SQL_ID ,
PLAN_HASH_VALUE ,
LPAD ( ' ' , 4 * DEPTH ) || OPERATION || OPTIONS OPERATION ,
OBJECT_NAME ,
CARDINALITY ,
BYTES ,
COST ,
TIME
FROM V$SQL_PLAN
where PLAN_HASH_VALUE = '964845277' ;
顯然在 object_id=1 0 時,結果集有 290011 條資料,佔比總表99.99% 的資料量,是不適合走索引範圍掃描,全表掃描會更高效些。
5 收集 OBJECT_ID 列直方圖資訊
在Oracle 中直方圖是一種對資料分佈質量情況進行描述的工具。
它會按照某一列不同值出現數量多少,以及出現的頻率高低來繪製資料的分佈情況,以便能夠指導優化器根據資料的分佈做出正確的選擇。正確的直方圖,將會對優化器做出正確的選擇發揮巨大的作用,使得SQL 語句執行成本最低,從而提升效能。
-- 下面收集欄位 OBJECT_ID 的直方圖:
SQL>
begin
dbms_stats.gather_table_stats('CJC',
'T1',
method_opt => 'for columns object_id size auto',
cascade => true);
end;
檢視 直方圖 資訊 :
select table_name,
column_name,
histogram,
num_distinct,
density,
last_analyzed
from user_tab_col_statistics
where table_name = 'T1'
and column_name = 'OBJECT_ID';
select *
from user_tab_histograms
where table_name = 'T1'
and column_name = 'OBJECT_ID';
6 重新執行 SQL ,檢視執行計劃
(1) 結果集少的執行計劃
SQL> select * from t1 where object_id=1;
(2) 結果集多的執行計劃
SQL> select * from t1 where object_id=10;
檢視結果集多的SQL 執行計劃已經發生了變化,執行了更高效的全表掃描。
select sql_text, sql_id, plan_hash_value, address, hash_value
from v$sql
where sql_text like 'select * from t1 where object_id%';
注意:
有幾種情況,在收集直方圖後,執行計劃不會馬上變化
一: SQL 的 CURSOR 沒有失效,不會重新生成執行計劃,可以通過如下幾種方法讓 SQL 的 CURSOR 失效。
(1) 在收集統計資訊時,指定引數 no_invalidate => false , 使這兩條 SQL 的 CURSOR 失效,進行重新解析。
我們通過以下儲存過程將這兩個 CURSOR 清除,這樣再執行就會重新解析了。
--填寫ADDRESS和HASH_VALUE值
BEGIN
DBMS_SHARED_POOL.PURGE('000000006EBF2F78,589030732', 'C');
DBMS_SHARED_POOL.PURGE('000000006F2B3660,2332556305', 'C');
END;
(2) 在收集統計時,加 no_invalidate => false 引數
begin
dbms_stats.gather_table_stats('CJC',
'T1',
method_opt => 'for columns object_id size 1',
cascade => true,
no_invalidate => false );
end;
(3) 重新整理整個 share pool( 生產環境謹慎使用 )
alter system flush shared_pool;
(4) 對這個表做 ddl 操作或授權或新增改變註釋等。
例如:
comment on column C JC . T1 . OBJECT _ID is 'PK_T 1 _ OBJECT_ID ';
comment on column C JC . T1 . OBJECT _ID is '';
二:資料庫 cursor_sharing 引數的值是否為 exact ,如果引數的值為 force ,相當於使用繫結變數,收集直方圖後,執行計劃可能沒有變化,解決辦法請參考下一節 Oracle 資料傾斜導致的問題 - 有繫結變數
歡迎關注我的微信公眾號"IT小Chen",共同學習,共同成長!!!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29785807/viewspace-2676749/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle資料傾斜導致的問題-有繫結變數Oracle變數
- Oracle面對“資料傾斜列使用繫結變數”場景的解決方案Oracle變數
- 【Spark篇】---Spark解決資料傾斜問題Spark
- 如何解決 Redis 資料傾斜、熱點等問題Redis
- 實戰 | Hive 資料傾斜問題定位排查及解決Hive
- 如何解決Hive中經常出現的資料傾斜問題Hive
- 【ORACLE】Oracle繫結變數知識梳理Oracle變數
- Spark學習——資料傾斜Spark
- 【epoll問題】EPOLLRDHUP使用導致無法接受資料
- 資料傾斜解決辦法
- IoT資料傾斜如何解決
- AdornerDecorator的CacheMode繫結和windows鎖屏導致TableControl鎖死問題Windows
- PostgreSQL DBA(193) - 資料傾斜下的HashJoinSQL
- Redis 切片叢集的資料傾斜分析Redis
- hive優化-資料傾斜優化Hive優化
- Spark 資料傾斜及其解決方案Spark
- hadoop 透過cachefile來避免資料傾斜Hadoop
- 【Hive】資料傾斜優化 shuffle, join, group byHive優化
- Hive千億級資料傾斜解決方案Hive
- 傾斜攝影三維模型的立體裁剪的問題分析模型
- oracle 序列值導致的主鍵衝突問題Oracle
- 數倉效能最佳化:傾斜最佳化-表示式計算傾斜的hint最佳化
- ORACLE DSG資料同步軟體程式導致資料庫無法正常關閉Oracle資料庫
- jmeter引數化導致反斜槓(\)被轉義JMeter
- 大資料SQL優化之資料傾斜解決案例全集大資料SQL優化
- 一種自平衡解決資料傾斜的分表方法
- 關於 iconv 轉碼導致資料丟失的問題
- 使用資料庫處理併發可能導致的問題資料庫
- 應用使用JNDI,資料庫無法連線,導致的程序無法啟動問題處理資料庫
- Laravel 專案一次釋出導致的 BUG(環境變數問題)Laravel變數
- Oracle中如何查詢未使用繫結變數的SQL語句?Oracle變數SQL
- 硬碟問題導致Gbase資料庫叢集SQL任務執行效率變慢硬碟資料庫SQL
- Spark效能最佳化篇三:資料傾斜調優Spark
- Chrome89針對sessionStorage的更新導致資料共享問題ChromeSession
- 【CURSOR】Oracle繫結變數、執行計劃對遊標的影響Oracle變數
- 重置資料庫密碼後導致網站無法訪問資料庫密碼網站
- 總結導致oracle資料庫主機CPU sys%高的一些原因Oracle資料庫
- ANALYZE導致的阻塞問題分析