国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

Oracle某行系統SQL優(yōu)化(案例四)

發(fā)布時(shí)間:2021-08-17 12:58 來(lái)源:ITPUB博客 閱讀:0 作者: 欄目: 數據庫

問(wèn)題說(shuō)明:   

業(yè)務(wù)人員反饋電信跑批速度慢,單條SQL耗時(shí)2s左右。
而聯(lián)通和移動(dòng)跑批速度正常,但條SQL耗時(shí)不超過(guò)0.2s。

環(huán)境說(shuō)明:

DB:Oracle 11.2.0.4.0 RAC
OS:AIX 7.1

問(wèn)題分析:

快、慢SQL文本如下:

慢SQL:

--電信1.6-1.8秒
select  msgserial, objaddr, endtime, retrytimes, srvtype, msgcont, report
  from (select msgserial,
               objaddr,
               endtime,
               retrytimes,
               srvtype,
               msgcont,
               report
          from CJCTABXXXX
         where msgstat = '0'
           and srcaddr = '11111'
           and xxxxxno = '2'
           and lastsndtime < to_char(sysdate, 'yyyymmddHH24MISS')
         order by msglevel, rpttime)
 where rownum <= 40;

快SQL:

--聯(lián)通0.1-0.2秒
select  msgserial, objaddr, endtime, retrytimes, srvtype, msgcont, report
  from (select msgserial,
               objaddr,
               endtime,
               retrytimes,
               srvtype,
               msgcont,
               report
          from CJCTABXXXX
         where msgstat = '0'
           and srcaddr = '11111'
           and xxxxxno = '1'
           and lastsndtime < to_char(sysdate, 'yyyymmddHH24MISS')
         order by msglevel, rpttime)
 where rownum <= 40;

可以看到,執行快慢兩個(gè)SQL,只有xxxxxno條件值取值不同,其他條件相同。

其中慢的SQL,條件為xxxxxno = '2',快的SQL,條件為xxxxxno = '1'。

那么猜測,一定是慢的SQL條件為xxxxxno = '2'時(shí)結果集比快的SQL大,所有速度才慢的,需要檢查xxxxxno不同取值下結果集大小。

---數據量: 74418(慢SQL)

select count(*)
  from (select msgserial,
               objaddr,
               endtime,
               retrytimes,
               srvtype,
               msgcont,
               report
          from CJCTABXXXX
         where msgstat = '0'
           and srcaddr = '11111'
           and xxxxxno = '2'
           and lastsndtime < to_char(sysdate, 'yyyymmddHH24MISS')
         order by msglevel, rpttime)

---數據量:411628(快SQL)

select count(*)
  from (select msgserial,
               objaddr,
               endtime,
               retrytimes,
               srvtype,
               msgcont,
               report
          from CJCTABXXXX
         where msgstat = '0'
           and srcaddr = '11111'
           and xxxxxno = '1'
           and lastsndtime < to_char(sysdate, 'yyyymmddHH24MISS')
         order by msglevel, rpttime)

疑惑1?

慢SQL的結果集有74418,遠小于快SQL的結果集411628,為什么慢SQL結果集小,邏輯讀反而很大呢?  

難道是慢的SQL執行計劃選錯了,導致雖然結果集小,但是cost很高?

分別生成快、慢兩個(gè)SQL執行計劃:

慢SQL執行計劃如下:

Elapsed: 00:00:01.98
Execution Plan
----------------------------------------------------------
-----------------------------------------------------------------------------------
| Id  | Operation                     | Name         | Rows  | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |              |    37 | 21904 |  1424   (1)|
|   1 |  COUNT STOPKEY                |              |       |       |            |
|   2 |   VIEW                        |              |    37 | 21904 |  1424   (1)|
|   3 |    TABLE ACCESS BY INDEX ROWID| CJCTABXXXX    |    37 |  8658 |  1424   (1)|
|   4 |     INDEX RANGE SCAN          | ICJCTABXXXX_4 |  1757 |       |    49   (0)|
-----------------------------------------------------------------------------------
Note
-----
   - 'PLAN_TABLE' is old version
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
     682865  consistent gets
          0  physical reads
          0  redo size
       6636  bytes sent via SQL*Net to client
        542  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         40  rows processed

快SQL執行計劃如下:

Execution Plan
----------------------------------------------------------
-----------------------------------------------------------------------------------
| Id  | Operation                     | Name         | Rows  | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |              |    40 | 23680 |   310   (0)|
|   1 |  COUNT STOPKEY                |              |       |       |            |
|   2 |   VIEW                        |              |    40 | 23680 |   310   (0)|
|   3 |    TABLE ACCESS BY INDEX ROWID| CJCTABXXXX    |    40 |  9360 |   310   (0)|
|   4 |     INDEX RANGE SCAN          | ICJCTABXXXX_4 |  1757 |       |    13   (0)|
-----------------------------------------------------------------------------------
Note
-----
   - 'PLAN_TABLE' is old version
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      16850  consistent gets
          0  physical reads
          0  redo size
       5866  bytes sent via SQL*Net to client
        542  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         40  rows processed

可以看到執行計劃也完全一樣,都是走的ICJCTABXXXX_4索引范圍掃描,

慢的SQL邏輯讀consistent gets(682865)遠高于快的SQL邏輯讀consistent gets(16850)。

疑惑2?

那么為什么會(huì )出現執行計劃相同,結果集小的邏輯讀反而更大呢?

問(wèn)題原因:

讓我們在認真看下快慢兩條SQL:

慢SQL:

--電信1.6-1.8秒
select  msgserial, objaddr, endtime, retrytimes, srvtype, msgcont, report
  from (select msgserial,
               objaddr,
               endtime,
               retrytimes,
               srvtype,
               msgcont,
               report
          from CJCTABXXXX
         where msgstat = '0'
           and srcaddr = '11111'
           and xxxxxno = '2'
           and lastsndtime < to_char(sysdate, 'yyyymmddHH24MISS')
         order by msglevel, rpttime)
 where rownum <= 40;

快SQL:

--聯(lián)通0.1-0.2秒
select  msgserial, objaddr, endtime, retrytimes, srvtype, msgcont, report
  from (select msgserial,
               objaddr,
               endtime,
               retrytimes,
               srvtype,
               msgcont,
               report
          from CJCTABXXXX
         where msgstat = '0'
           and srcaddr = '11111'
           and xxxxxno = '1'
           and lastsndtime < to_char(sysdate, 'yyyymmddHH24MISS')
         order by msglevel, rpttime)
 where rownum <= 40;

在不考慮xxxxxno條件時(shí),兩個(gè)SQL文本是完全一樣的,分別是對msglevel, rpttime排序后取前40條記錄。

那么出現執行計劃相同,結果集小的邏輯讀反而更大的原因很有可能是因為:

1.SQL并沒(méi)有完全執行完order by排序完、回表完然后才去執行rownum<=40操作。

而是邊對部分排序和回表邊取出部分rownum<=40的值。

2.檢查order by msglevel, rpttime排序的兩個(gè)列都包含在同一個(gè)索引里,

也就是這兩列排序操作不需要訪(fǎng)問(wèn)數據塊,只需范圍索引塊,

然后回表返回其他列的值,同時(shí)邊回表,邊返回部分rownum <= 40的值。

3.那么為什么xxxxxno過(guò)濾性差,結果集多的邏輯讀反而少了,這是因為結果集越大,越容易找到前40條符合條件的值。

例如:

有一個(gè)大紙箱,里面混合裝了100個(gè)球,其中紅色球80個(gè),籃色球10個(gè),粉色球10個(gè),

請問(wèn)在紙箱里分別取出10個(gè)紅色球、10個(gè)籃色球、10個(gè)粉色球,哪個(gè)速度更快呢?

顯然是取出10個(gè)紅色球速度更快,因為紅色球數量最多,更容易找到10個(gè)紅色球。

本次案例也是類(lèi)似的道理,因為xxxxxno條件過(guò)濾性好的結果集小,想取出前40個(gè)值時(shí),需要掃描更多的塊,索引邏輯讀更高,速度更慢。

解決方案:

可以考慮調整組合索引,將xxxxxno列加入到組合索引中,具體方案還需要充分測試后在使用。

#####chenjuchao 2021-08-15 21:05#####

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

又黄又网站国产| 国产精品无码免费播放| 国产精品露脸视频观看| 久久亚洲精品11p| 99精品久久久久久久婷婷| 久久国产精品成人影院|