閱讀731 返回首頁    go 技術社區[雲棲]


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

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

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

640?wx_fmt=png&wxfrom=5&wx_lazy=1

產生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。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

Rem 這裏我們修改了NLS_SORT參數,
Rem 再來查看SQL的遊標數。

SQL> alter session set nls_sort = 'SCHINESE_RADICAL_M'; Session altered.

640?wx_fmt=png&wxfrom=5&wx_lazy=1

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

REM 以下修改了優化器模式,
REM 又一個新的子遊標將會因此而產生。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

REM 可以看到,第二個子遊標是因為優化器
REM 模式不匹配產生的,OPTIMIZER_MODE_MISMATCH.

REM 以下步驟,我們綁定了不同長度的綁定變量,
REM 由此又可能產生新的SQL版本。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

REM 我們看到的第三個子遊標就是
REM 因為綁定變量長度不同而產生的。


從Oracle 9i開始,Oracle對中文語言方式(Simplified Chinese和Traditional Chinese)提供了多種排序方式。主要由以下四種,大家可以進行修改嚐試:

SCHINESE_RADICAL_M   針對簡體中文,按照部首(第一順序)、筆劃(第二順序)排序
SCHINESE_STROKE_M    針對簡體中文,按照筆劃(第一順序)、部首(第二順序)排序
SCHINESE_PINYIN_M       針對簡體中文,按照拚音排序
TCHINESE_RADICAL_M    針對繁體中文,按照部首(第一順序)、筆劃(第二順序)排序
TCHINESE_STROKE_M     針對繁體中文,按照筆劃(第一順序)、部首(第二順序)排序

當然可以逐一嚐試:

640?wx_fmt=png&wxfrom=5&wx_lazy=1

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


本文出自數據和雲公眾號,原文鏈接


最後更新:2017-07-17 17:03:19

  上一篇:go  【重大漏洞預警】Windows兩個關鍵遠程代碼執行漏洞
  下一篇:go  新浪微博癱瘓,有人開心有人哭