最近的幾個技術問題總結和答疑(九)

jeanron100發表於2016-09-08
    最近的瑣事比較多,而提問題的朋友還是不少,很多訊息都沒有來得及回覆,各種事情一堆起來,不少問題想起來已經過了好幾天了,所以還是來整理一篇技術問答為好。
    首先是很多朋友問我關於半自動化搭建Data Guard的指令碼,我寫了幾篇文章來介紹思路,自己也提了不少的改進,團隊內部也溝透過了,一直遲遲沒有釋出出來是因為我覺得目前的實現方式可能對於我的工作能夠極大提高,但是很多朋友使用的環境可能沒有中控的概念,所以不是很通用,所以我想做一些改變,還有一個是裡面的有些邏輯我想改改,至少簡化一下。但是一直是思想的潛行者,行動的矮子,這件事情拖了不少日子。真是慚愧,我力爭下週末前分享出來,然後附上簡單的使用說明。
    最近開始實踐時間管理,所以對於微信上的事情花的精力就少了很多,這樣可以讓我更加專注,可能隔一段時間我會看看聊天記錄。不知不覺,又堆積了快一百條未讀訊息,目前我使用的時間管理工具是日事清,至少這個工具能夠手機端,電腦端都可以同步,這個完全符合我的習慣,使用起來還不錯,其實越是指定詳細的計劃,越是發現自己很多東西都需要學習,都需要改進。看來分得了輕重緩急,而且能夠實踐到位是一件很不容易的事情。我發現很多時候都會有急於求成的心態,所以工作列上的有些東西突然加上去了,而有些計劃內的東西就耽擱了,長此以往會逐步有拖延的現象,這個一定要引以為戒。
    然後來解答幾個技術問題。
    今天在微信群中看到葉老師提問關於得到DB time的曲線圖,其實要得到這樣的圖形,有兩種思路,一種就是得到實時的資料,這個就需要指定頻度來抓取狀態資料,比如抓取實時DB time,根據這些狀態點資訊得到一個完整的曲線圖,這個在Zabbix監控體系中是沒有問題的,而且基於Oracle的監控可以使用Orabbix,要檢視按天,按周,按月的曲線圖,這個在Zatree裡面是完全支援的,目前我們也這麼用;而另外一種思路就是基於快照,這個得到的資料頻度可能是半小時或者一小時,狀態略粗一些,我下午整理了一個shell指令碼,感興趣百度網盤可以檢視
    而自我上次發了一篇關於執行計劃直方圖的文章一來,還是有幾個朋友對這方面很關注,提了不少的建議。有些朋友問那個15個字元是什麼意思,沒看明白,我做個小測試來說明。
建立一個測試表。
>  create table test_stats (order_id varchar2(64),user_id varchar2(64),channel_id number);
Table created.

> insert into test_stats values('0000000000001241414','test',1);
1 row created.

> insert into test_stats values('0000000000001251414','test2',2);
1 row created.

> insert into test_stats values('0000000000001251514','test3',2);
1 row created.

> commit;
Commit complete.

如果想看更多細節,可以開啟10046事件。
ALTER SESSION SET EVENTS '10046 trace name context forever, level 12'
收集統計資訊
exec dbms_stats.gather_table_stats(tabname => 'test_stats',ownname => 'N1',method_opt => 'FOR ALL COLUMNS SIZE AUTO');
ALTER SESSION SET EVENTS '10046 trace name context off'
收集統計資訊使用了auto選項呢,可以看到,都沒有生成直方圖資訊。
SELECT COLUMN_NAME, NUM_DISTINCT, NUM_BUCKETS, HISTOGRAM
FROM   USER_TAB_COL_STATISTICS
WHERE  TABLE_NAME = 'TEST_STATS' AND COLUMN_NAME IN ('ORDER_ID','USER_ID') ;
COLUMN_NAME             NUM_DISTINCT NUM_BUCKETS HISTOGRAM
---------------------- ------------ ----------- ------------------------------
ORDER_ID                       3           1 NONE
USER_ID                         3           1 NONE

但是實際上檢視資料字典可以看到還是依舊存在兩個預設的bucket.
select to_char(endpoint_value) value,endpoint_number,column_name from dba_tab_histograms where table_name = 'TEST_STATS' and column_name in ('ORDER_ID','USER_ID') ORDER BY endpoint_number;
VALUE                                    ENDPOINT_NUMBER COLUMN_NAME
---------------------------------------- --------------- --------------------
250207622735984000000000000000000000                   0 ORDER_ID
604364106098959000000000000000000000                   0 USER_ID
250207622735984000000000000000000000                   1 ORDER_ID
604364106160614000000000000000000000                   1 USER_ID
這個值是怎麼算出來的。
首先對欄位order_id的max值做一個dump
SQL> select to_char(substrb(dump(max("ORDER_ID"),16,0,32),1,120))  from "N1"."TEST_STATS" t ;
TO_CHAR(SUBSTRB(DUMP(MAX("ORDER_ID"),16,0,32),1,120))
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Typ=1 Len=19: 30,30,30,30,30,30,30,30,30,30,30,30,31,32,35,31,35,31,34
然後取前30位,轉為十六進位制,得到的是2502開始的一長串數字。
SQL> select to_number('303030303030303030303030313235','xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') aa from dual;
                                                           AA
-------------------------------------------------------------
                         250207622735984164311304858405777973
而得到的這一長串數字的前15位是什麼呢?                      
SQL>  select substr('250207622735984164311304858405777973',1,15) from dual;
SUBSTR('2502076227359841643113
------------------------------
250207622735984
我們這個時候來看看直方圖資料字典的資訊。可以看到value是250207622735984000000000000000000000,前面的15位就是我們計算得到的這個數字。
select to_char(endpoint_value) value,endpoint_number,column_name from dba_tab_histograms where table_name = 'TEST_STATS' and column_name in ('ORDER_ID') ORDER BY endpoint_number;
VALUE                                    ENDPOINT_NUMBER COLUMN_NAME
---------------------------------------- --------------- --------------------
250207622735984000000000000000000000                   0 ORDER_ID
250207622735984000000000000000000000                   1 ORDER_ID
而如果我們重新收集統計資訊,指定bucket為20
exec dbms_stats.gather_table_stats(tabname => 'test_stats',ownname => 'N1',method_opt => 'FOR  COLUMNS SIZE 20  ORDER_ID');
然後再次檢視,其實這個時候只生成了3個,因為我只插入了3行資料,樣本太少,但是檢視value值是一樣的,這樣也就很難有所差別,其實也算是丟失了一些精度導致。
SQL>  select to_char(endpoint_value) value,endpoint_number,column_name,ENDPOINT_ACTUAL_VALUE from dba_tab_histograms where table_name = 'TEST_STATS' and column_name in ('ORDER_ID') ORDER BY endpoint_number;

VALUE                                    ENDPOINT_NUMBER COLUMN_NAME          ENDPOINT_ACTUAL_VALUE
---------------------------------------- --------------- -------------------- ----------------------------------------
250207622735984000000000000000000000                   1 ORDER_ID             0000000000001241414
250207622735984000000000000000000000                   2 ORDER_ID             0000000000001251414
250207622735984000000000000000000000                   3 ORDER_ID             0000000000001251514




來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-2124739/,如需轉載,請註明出處,否則將追究法律責任。

相關文章