【Oracle】Oracle 12c DB In-Memory入門實驗手冊(四)
(四)查詢IM中的資料
之前的三篇我們分別介紹了以下三部分內容,感興趣的朋友可以去看一下:
載入資料到IM:http://blog.csdn.net/badly9/article/details/49777993
IM壓縮:http://blog.csdn.net/badly9/article/details/49815643
4.1載入測試表到IM中
將測試表設定IM屬性,同時保證她們被載入到IM中。
1.開啟測試表的IM屬性。
SQL> ALTER TABLE DWB_RTL_SLS_RETRN_LINE_ITEM INMEMORY;
Table altered.
SQL> ALTER TABLE DWB_RTL_TNDR_LI INMEMORY;
Table altered.
SQL> ALTER TABLE DWB_RTL_TRX INMEMORY;
Table altered.
SQL> ALTER TABLE DWR_ORG_BSNS_UNIT INMEMORY;
Table altered.
SQL> ALTER TABLE DWR_SKU_ITEM INMEMORY;
Table altered.
2.確認這些表已經開啟IM屬性
SQL> SELECT TABLE_NAME, INMEMORY, INMEMORY_PRIORITY,
2 INMEMORY_DISTRIBUTE, INMEMORY_COMPRESSION
3 FROM USER_TABLES;
TABLE_NAME INMEMORY INMEMORY INMEMORY_DISTRI INMEMORY_COMPRESS
------------------------------ -------- -------- --------------- -----------------
DWB_RTL_SLS_RETRN_LINE_ITEM
DWB_RTL_TNDR_LI
DWB_RTL_TRX
DWR_ORG_BSNS_UNIT ENABLED NONE AUTO FOR QUERY LOW
DWR_SKU_ITEM ENABLED NONE AUTO FOR QUERY LOW
可以看到有三張表的IM屬性顯示為空,因為它們是分割槽表,所以要從USER_TAB_PARTITIONS中檢視:
SQL> SELECT TABLE_NAME, INMEMORY, INMEMORY_PRIORITY,
2 INMEMORY_DISTRIBUTE, INMEMORY_COMPRESSION
3 FROM USER_TAB_PARTITIONS;
TABLE_NAME INMEMORY INMEMORY INMEMORY_DISTRI INMEMORY_COMPRESS
---------------------------------------- -------- -------- --------------- -----------------
DWB_RTL_SLS_RETRN_LINE_ITEM ENABLED NONE AUTO FOR QUERY LOW
DWB_RTL_SLS_RETRN_LINE_ITEM ENABLED NONE AUTO FOR QUERY LOW
DWB_RTL_SLS_RETRN_LINE_ITEM ENABLED NONE AUTO FOR QUERY LOW
DWB_RTL_SLS_RETRN_LINE_ITEM ENABLED NONE AUTO FOR QUERY LOW
DWB_RTL_TNDR_LI ENABLED NONE AUTO FOR QUERY LOW
DWB_RTL_TNDR_LI ENABLED NONE AUTO FOR QUERY LOW
DWB_RTL_TNDR_LI ENABLED NONE AUTO FOR QUERY LOW
DWB_RTL_TNDR_LI ENABLED NONE AUTO FOR QUERY LOW
DWB_RTL_TRX ENABLED NONE AUTO FOR QUERY LOW
DWB_RTL_TRX ENABLED NONE AUTO FOR QUERY LOW
DWB_RTL_TRX ENABLED NONE AUTO FOR QUERY LOW
DWB_RTL_TRX ENABLED NONE AUTO FOR QUERY LOW
12 rows selected.
3.將IM中其他表置為NO INMEMORY。
查詢IM中的表
SQL> COL OWNER FORMAT A15
SQL> COL SEGMENT_NAME FORMAT A20
SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_SIZE, POPULATE_STATUS
2 FROM V$IM_SEGMENTS;
OWNER SEGMENT_NAME INMEMORY_SIZE POPULATE_
--------------- -------------------- ------------- ---------
BADLY9 SALES_INM3 2228224 COMPLETED
BADLY9 SALES_INM_2 5439488 COMPLETED
BADLY9 SALES_INM_4 32309248 COMPLETED
BADLY9 COSTS 1179648 COMPLETED
BADLY9 SALES_INM_1 28114944 COMPLETED
BADLY9 SALES_INM_3 4325376 COMPLETED
BADLY9 SALES_INM2 3342336 COMPLETED
BADLY9 SALES 7536640 COMPLETED
8 rows selected.
置為NO INMEMORY
ALTER TABLE BADLY9.SALES_INM3 NO INMEMORY;
ALTER TABLE BADLY9.SALES_INM_2 NO INMEMORY;
ALTER TABLE BADLY9.SALES_INM_4 NO INMEMORY;
ALTER TABLE BADLY9.COSTS NO INMEMORY;
ALTER TABLE BADLY9.SALES_INM_1 NO INMEMORY;
ALTER TABLE BADLY9.SALES_INM_3 NO INMEMORY;
ALTER TABLE BADLY9.SALES_INM2 NO INMEMORY;
ALTER TABLE BADLY9.SALES NO INMEMORY;
確認一下:
SQL> COL OWNER FORMAT A15
SQL> COL SEGMENT_NAME FORMAT A20
SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_SIZE, POPULATE_STATUS
2 FROM V$IM_SEGMENTS;
no rows selected
4.通過查詢將測試表載入到IM中
SELECT COUNT(*) FROM DWB_RTL_SLS_RETRN_LINE_ITEM;
SELECT COUNT(*) FROM DWB_RTL_TNDR_LI;
SELECT COUNT(*) FROM DWB_RTL_TRX;
SELECT COUNT(*) FROM DWR_ORG_BSNS_UNIT;
SELECT COUNT(*) FROM DWR_SKU_ITEM;
確認表已經載入到IM中
SQL> COL OWNER FORMAT A15
SQL> COL SEGMENT_NAME FORMAT A30
SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_SIZE, POPULATE_STATUS
2 FROM V$IM_SEGMENTS;
OWNER SEGMENT_NAME INMEMORY_SIZE POPULATE_
--------------- ------------------------------ ------------- ---------
RTL DWB_RTL_SLS_RETRN_LINE_ITEM 165609472 COMPLETED
RTL DWR_SKU_ITEM 5373952 COMPLETED
RTL DWB_RTL_TNDR_LI 30605312 COMPLETED
RTL DWB_RTL_SLS_RETRN_LINE_ITEM 166723584 COMPLETED
RTL DWB_RTL_TRX 23265280 COMPLETED
RTL DWR_ORG_BSNS_UNIT 1179648 COMPLETED
RTL DWB_RTL_TNDR_LI 23265280 COMPLETED
RTL DWB_RTL_SLS_RETRN_LINE_ITEM 166723584 COMPLETED
RTL DWB_RTL_TRX 23265280 COMPLETED
RTL DWB_RTL_TNDR_LI 23265280 COMPLETED
RTL DWB_RTL_TRX 23265280 COMPLETED
11 rows selected.
4.2 簡單聚合函式查詢
1.檢視使用IM查詢情況下的時間
SQL> set timing on
SQL> SELECT MAX(EXTENDED_AMT) FROM DWB_RTL_SLS_RETRN_LINE_ITEM;
MAX(EXTENDED_AMT)
-----------------
10.55
Elapsed: 00:00:00.34
2.禁用INMEMORY_QUERY,重新查詢
SQL> ALTER SESSION SET INMEMORY_QUERY=DISABLE;
Session altered.
Elapsed: 00:00:00.13
SQL> SELECT MAX(EXTENDED_AMT) FROM DWB_RTL_SLS_RETRN_LINE_ITEM;
MAX(EXTENDED_AMT)
-----------------
10.55
Elapsed: 00:00:13.75
3.恢復環境開啟INMEMORY_QUERY
SQL> ALTER SESSION SET INMEMORY_QUERY=ENABLE;
Session altered.
Elapsed: 00:00:00.00
SQL> set timing off
4.比較兩次的執行計劃
(1)
SELECT MAX(EXTENDED_AMT) FROM DWB_RTL_SLS_RETRN_LINE_ITEM;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
(2)
ALTER SESSION SET INMEMORY_QUERY=DISABLE;
SELECT MAX(EXTENDED_AMT) FROM DWB_RTL_SLS_RETRN_LINE_ITEM;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
ALTER SESSION SET INMEMORY_QUERY=ENABLE;
具體輸出:
(1)
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 8q5xwrfukc71s, child number 2
-------------------------------------
SELECT MAX(EXTENDED_AMT) FROM DWB_RTL_SLS_RETRN_LINE_ITEM
Plan hash value: 1560629232
----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 57829 (100)| | | |
| 1 | SORT AGGREGATE | | 1 | 4 | | | | |
| 2 | PARTITION RANGE ALL | | 44 | 176 | 57829 (1)| 00:00:03 | 1 |1048575|
| 3 | TABLE ACCESS INMEMORY FULL| DWB_RTL_SLS_RETRN_LINE_ITEM | 44 | 176 | 57829 (1)| 00:00:03 | 1 |1048575|
----------------------------------------------------------------------------------------------------------------------------
Note
-----
- statistics feedback used for this statement
(2)
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 8q5xwrfukc71s, child number 1
-------------------------------------
SELECT MAX(EXTENDED_AMT) FROM DWB_RTL_SLS_RETRN_LINE_ITEM
Plan hash value: 1560629232
--------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 58010 (100)| | | |
| 1 | SORT AGGREGATE | | 1 | 4 | | | | |
| 2 | PARTITION RANGE ALL| | 27M| 105M| 58010 (1)| 00:00:03 | 1 |1048575|
| 3 | TABLE ACCESS FULL | DWB_RTL_SLS_RETRN_LINE_ITEM | 27M| 105M| 58010 (1)| 00:00:03 | 1 |1048575|
--------------------------------------------------------------------------------------------------------------------
可以看到一個是TABLE ACCESS INMEMORY FULL,一個是TABLE ACCESS FULL
4.3關於IM的統計資訊
我們可以通過結合V$MYSTAT和V$STATNAME來檢視關於IM的統計資訊
實驗過程如下:
1.通過V$STATNAME檢視檢視IM統計項
SQL> SELECT DISPLAY_NAME
2 FROM V$STATNAME
3 WHERE DISPLAY_NAME LIKE 'IM %';
DISPLAY_NAME
----------------------------------------------------------------
IM populate blocks invalid
IM populate transactions check
IM populate undo segheader rollback
IM populate undo records applied
......
IM zzzz spare9
IM zzzz spare10
198 rows selected.
可以看到有198個相關的統計項,然而在日常管理中我們並不是都需要,主要用到的有以下幾項:
IM scan bytes uncompressed:在未優化掃描優先順序的情況下,在所有CU(壓縮單元)中未壓縮的大小,單位為bytes。
IM scan bytes in-memory:在未優化掃描優先順序的情況下,在所有CU中壓縮的大小,單位為bytes。
IM scan CUs columns accessed:掃描中總共訪問的CU的總數。
IM scan CUs columns theoretical max:如果每個掃描都需要訪問IMCU中所有的列,那麼理論上最多訪問的CU數。
2.檢視一下需要關注的統計項
SQL> SELECT DISPLAY_NAME, VALUE
2 FROM V$MYSTAT m, V$STATNAME n
3 WHERE m.STATISTIC# = n.STATISTIC#
4 AND n.DISPLAY_NAME IN (
5 'IM scan bytes in-memory',
6 'IM scan bytes uncompressed',
7 'IM scan CUs columns accessed',
8 'IM scan CUs columns theoretical max');
DISPLAY_NAME VALUE
---------------------------------------------------------------- ----------
IM scan bytes in-memory 0
IM scan bytes uncompressed 0
IM scan CUs columns accessed 0
IM scan CUs columns theoretical max 0
3.執行一下測試查詢:
SQL> SELECT MAX(EXTENDED_AMT) FROM DWB_RTL_SLS_RETRN_LINE_ITEM;
MAX(EXTENDED_AMT)
-----------------
10.55
4.再檢視一下關注的統計項
SQL> SELECT DISPLAY_NAME, VALUE
2 FROM V$MYSTAT m, V$STATNAME n
3 WHERE m.STATISTIC# = n.STATISTIC#
4 AND n.DISPLAY_NAME IN (
5 'IM scan bytes in-memory',
6 'IM scan bytes uncompressed',
7 'IM scan CUs columns accessed',
8 'IM scan CUs columns theoretical max');
DISPLAY_NAME VALUE
---------------------------------------------------------------- ----------
IM scan bytes in-memory 481927401
IM scan bytes uncompressed 3044446804
IM scan CUs columns accessed 44
IM scan CUs columns theoretical max 704
注:該測試表有16列 704=44*16
4.4帶過濾條件的查詢
對於帶過濾條件的查詢,IM還有額外的技術來進行加速,那就是儲存索引,如果在where條件中指定了關於min/max的範圍,那麼一個CU中包含的值並不在這個min/max範圍內,則會被跳過,不進行掃描,以提升查詢速度。
相關的統計項我們關注以下項:
IM scan segments minmax eligible:所有需要掃描的包含資料的CU數量。
IM scan CUs pruned:通過儲存索引被篩選掉的CU數量。
實驗過程如下:
1.執行查詢:
SQL> SET TIMING ON
SQL> SELECT SUM(EXTENDED_AMT)
2 FROM RTL.DWB_RTL_SLS_RETRN_LINE_ITEM
3 WHERE ACTN_CD = 'Return';
SUM(EXTENDED_AMT)
-----------------
112775.59
Elapsed: 00:00:00.03
SQL> SET TIMING OFF
2.檢視關注的統計項:
SQL> SELECT DISPLAY_NAME, VALUE
2 FROM V$MYSTAT m, V$STATNAME n
3 WHERE m.STATISTIC# = n.STATISTIC#
4 AND n.DISPLAY_NAME IN (
5 'IM scan segments minmax eligible',
6 'IM scan CUs pruned',
7 'IM scan CUs columns accessed');
DISPLAY_NAME VALUE
---------------------------------------------------------------- ----------
IM scan CUs columns accessed 6
IM scan CUs pruned 41
IM scan segments minmax eligible 44
可以看到最終實際訪問的CU數量只有6,過濾掉了41個CU,原本要訪問的是44個CU,這裡可以看到44-41明明是3,為啥最後訪問的是6呢,那多出來的3是訪問儲存索引等必要的開銷。
4.5多過濾條件查詢
4.4介紹了對於單個過濾條件,IM可以使用儲存索引來加速查詢速度,那麼對於多個過濾條件,IM是否還能使用儲存索引來加快查詢速度呢?答案是肯定的,接下來看看我們下邊的實驗:
實驗過程:
1.在select語句中使用2個查詢條件:
SQL> SELECT SUM(EXTENDED_AMT)
2 FROM RTL.DWB_RTL_SLS_RETRN_LINE_ITEM
3 WHERE ACTN_CD = 'Return'
4 AND QTY = 2;
SUM(EXTENDED_AMT)
-----------------
6406.7
2.查詢關注的IM統計項:
SQL> SELECT DISPLAY_NAME, VALUE
2 FROM V$MYSTAT m, V$STATNAME n
3 WHERE m.STATISTIC# = n.STATISTIC#
4 AND n.DISPLAY_NAME IN (
5 'IM scan segments minmax eligible',
6 'IM scan CUs pruned',
7 'IM scan CUs columns accessed',
8 'IM scan rows',
9 'IM scan rows valid',
10 'IM scan rows optimized');
DISPLAY_NAME VALUE
---------------------------------------------------------------- ----------
IM scan CUs columns accessed 9
IM scan rows 27541321
IM scan rows valid 1570478
IM scan rows optimized 25970843
IM scan CUs pruned 41
IM scan segments minmax eligible 44
6 rows selected.
這裡我們多加了幾個統計項:
IM scan rows:IM中應該掃描的行數
IM scan rows optimized IM中被優化掉的掃描行數
IM scan rows valid:IM中實際掃描的行數
可以看到在本次查詢中IM依然使用了儲存索引IM scan segments minmax eligible為44,IM scan CUs pruned 為41,相差仍未3,但.最後真正掃描的CU數目為9,有所升高。
3.那麼再測試一下使用3個過濾條件的查詢
SQL> SELECT SUM(EXTENDED_AMT)
2 FROM RTL.DWB_RTL_SLS_RETRN_LINE_ITEM
3 WHERE ACTN_CD = 'Return'
4 AND QTY = 2
5 AND BEGIN_DT_TIMESTAMP =
6 TO_TIMESTAMP('01/01/2014 08:00','MM/DD/YYYY HH24:MI');
SUM(EXTENDED_AMT)
-----------------
SQL> SELECT DISPLAY_NAME, VALUE
2 FROM V$MYSTAT m, V$STATNAME n
3 WHERE m.STATISTIC# = n.STATISTIC#
4 AND n.DISPLAY_NAME IN (
5 'IM scan segments minmax eligible',
6 'IM scan CUs pruned',
7 'IM scan CUs columns accessed',
8 'IM scan rows',
9 'IM scan rows valid',
10 'IM scan rows optimized');
DISPLAY_NAME