標籤:
SQL SERVER下產生隨機資料幹得多,可是到了Oracle下我就傻了。沒用過Oracle,不知道該怎麼辦?SQL SERVER下依靠TABLESAMPLE或者CHECKSUM(NEWID())來做隨機抽樣,Oracle則有它自己的隨機抽樣方法。
這裡找到一篇文章講得挺好的:http://www.cnblogs.com/Athrun/archive/2009/04/25/1443619.html
Oracle下隨機取樣相關的辦法有:
1)SAMPLE(percent)
2)SAMPLE BLOCK(percent)
3)dbms_random包,包括dbms_random.random,dbms_random.value
4)sys_guid()
差不多就是上面這幾種吧
那其實我覺得各有各的特點,如果單論效能那肯定SAMPLE的效能最好了,Oracle的採樣技術減少了過程需要掃描的BLOCK數量,而SAMPLE BLOCK(percent)和SAMPLE(percent)比誰效能要更好就不清楚了,不曉得Oracle掃描的時候是一個BLOCK取一行還是把整個BLOCK的行都取出來。我想SAMPLE BLOCK的效能應該是要比SAMPLE的效能要更好。不過離散分布率要更低。
其實和SQL SERVER下的TABLESAMPLE一樣,用SAMPLE的問題在於離散率。如果我們對某個取樣資料的離散率要求很高,那顯然dbms_random和sys_guid()應該比SAMPLE要做得更好。
這裡對比一下SAMPLE, dbms_random.random和dbms_random.value的差異
select * from NUMBERS SAMPLE(0.1) order by ID ASC;select * from ( select * from NUMBERSorder by dbms_random.random )where rownum <= 100order by ID ASC; select * from ( select * from NUMBERSorder by dbms_random.value )where rownum <= 100order by ID ASC;
SAMPLE的結果輸出了112行,表的行數是10萬行,percent為0.1,按道理應該輸出100行整。證明SAMPLE對於行數還是不確定。這裡還得再離散提取前100行出來。不過我相信它的效能應該是最好的,耗時上也證明了這一點。而且和後面兩個對比資料分布的離散化也是差不多,我之前擔憂的會出現同一個BLOCK下的行多數或者都被提出來的情況似乎是多餘,這裡的資料分布和其他兩者相近。至於說其他兩者的效能似乎相差無幾,基本一樣。不過這裡有篇博文好像說random比value效能要好,http://www.blogjava.net/pengpenglin/archive/2009/03/19/206796.html
dbms_random.random的結果
dbms_random.value的結果
有幾點要注意的是
1) SAMPLE只對單表有效,遠端資料表和串連查詢無效
2)SAMPLE會使SQL自動使用CBO
這裡摘取別人文章中關於sys.guid()函數的注釋
注:
在使1)方法時,即使用sys_guid() 這種方法時,有時會擷取到相同的記錄,即和前一次查詢的結果集是一樣的,我尋找了相關資料,有些說是和作業系統有關,在windows平台下正常,擷取到的資料是隨機的,而在linux等平台下始終是相同不變的資料集,有些說是因為sys_guid()函數本身的問題,即sys_guid()會在查詢上產生一個16位元組的通用唯一識別碼,這個標識符在絕大部分平台上由一個宿主標識符和進程或進程的線程標識符組成,這就是說,它很可能是隨機的,但是並不表示一定是百分之百的這樣.
在Oracle中一般擷取隨機數的方法是:
select trunc(dbms_random.value(0, 1000)) from dual; (0-1000的整數)
select dbms_random.value(0, 1000) from dual; (0-1000的浮點數)
Oracle ->> 隨機函數