1. 程式人生 > >Oracle 資料庫之最:你見過最高的 SQL Version 是多少?

Oracle 資料庫之最:你見過最高的 SQL Version 是多少?

Oracle資料庫中執行的SQL,很多時候會因為種種原因產生多個不同的執行版本,一個遊標的版本過多很容易引起資料庫的效能問題,甚至故障。

有時候一個SQL的版本數量可能多達數萬個,以下是我之前在”雲和恩墨大講堂”分享過的一個案例。這個報告中的 SQL,最高達到了26萬個 SQL 版本。算是我見過的“之最”之一。

SQL

產生SQL多版本的原因很多,通過如下的一些測試我們可以稍微來看看如何分析和找到可能的原因。

以下作為一個基礎測試資料,一條基本的SQL查詢:

create table t1(c1 int, c2 nvarchar2(100));
alter system flush shared_pool;


var b1 number;
var b2 varchar2(10);
exec :b1 := 1;
exec :b2 := ‘0’;
select /* test */ * from t1 where c1 = :b1 and c2 = :b2 order by c2;

如果我們修改了優化器引數、環境變數、繫結變數等,都可能使得SQL發生重新解析,產生不同的子游標,也就是不同的VERSION。

VERSION

Rem 這裡我們修改了NLS_SORT引數,
Rem 再來檢視SQL的遊標數。
SQL> alter session set nls_sort = 'SCHINESE_RADICAL_M';

Session altered.
REM 注意,以上第一個Child就是因為
REM 語言不匹配產生的(LANGUAGE_MISMATCH)

REM 以下修改了優化器模式,
REM 又一個新的子游標將會因此而產生。
REM 
REM 可以看到,第二個子游標是因為優化器
REM 模式不匹配產生的,OPTIMIZER_MODE_MISMATCH.
REM 以下步驟,我們綁定了不同長度的繫結變數,
REM 由此又可能產生新的SQL版本。
REM 我們看到的第三個子游標就是
REM 因為繫結變數長度不同而產生的。
從Oracle 9i開始,Oracle對中文語言方式(Simplified Chinese和Traditional Chinese)提供了多種排序方式。主要由以下四種,大家可以進行修改嘗試:
SCHINESE_RADICAL_M   針對簡體中文,按照部首(第一順序)、筆劃(第二順序)排序
SCHINESE_STROKE_M    針對簡體中文,按照筆劃(第一順序)、部首(第二順序)排序
SCHINESE_PINYIN_M       針對簡體中文,按照拼音排序
TCHINESE_RADICAL_M    針對繁體中文,按照部首(第一順序)、筆劃(第二順序)排序
TCHINESE_STROKE_M     針對繁體中文,按照筆劃(第一順序)、部首(第二順序)排序
當然可以逐一嘗試:

Oracle

以上測試是基於11.2.0.3版本,在Oracle 12c中,相關的可能因素已經多達64個,參考官方手冊可以瞭解 V$SQL_SHARED_CURSOR 的更詳細資訊。

文章來自微信公眾號:資料和雲