精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

數據倉庫中的SQL性能優化(Hive篇)

大數據 數據倉庫
一個Hive查詢生成多個map reduce job,一個map reduce job又有map,reduce,spill,shuffle,sort等多個階段,所以針對hive查詢的優化可以大致分為針對M/R中單個步驟的優化,針對M/R全局的優化,和針對整個查詢(多M/R job)的優化,下文會分別闡述。

 一個Hive查詢生成多個map reduce job,一個map reduce job又有map,reduce,spill,shuffle,sort等多個階段,所以針對hive查詢的優化可以大致分為針對M/R中單個步驟的優化,針對M/R全局的優化,和針對整個查詢(多M/R job)的優化,下文會分別闡述。

要說明的是,這個優化只是針對Hive 0.9版本。由于Hortonwork發起了Stinger項目,Hive后續版本應該能更加快速的響應查詢。目前已經發布的Hive 0.11就有不少新feature,比如針對數據倉庫中常用的星型模型的優化等等,這些就不在本文的討論范圍之內了。  

 

 

Map階段的優化

Map階段的優化,主要是確定合適的map數。那么首先要了解map數的計算公式,即:

  1. num_map_tasks = max[${mapred.min.split.size}, 
  2. min(${dfs.block.size}, ${mapred.max.split.size})]  

其中mapred.min.split.size指的是數據的最小分割單元大小;mapred.max.split.size指的是數據的***分割單元大小;dfs.block.size指的是HDFS設置的數據塊大小。

一般來說dfs.block.size這個值是一個已經指定好的值,而且這個參數默認情況下hive是識別不到的(除非在hive-site.xml中明確指定),即:

  1. hive> set dfs.block.size
  2. dfs.block.size is undefined  

所以默認情況下只有mapred.min.split.size和mapred.max.split.size這兩個參數(本節內容后面就以min和max指代這兩個參數)來決定map數量。

在hive中min的默認值是1B,max的默認值是256MB,即:

  1. hive> set mapred.min.split.size
  2. mapred.min.split.size=1 
  3. hive> set mapred.max.split.size
  4. mapred.max.split.size=256000000  

所以如果不做修改的話,就是1個map task處理256MB數據,我們就以調整max為主。通過調整max可以起到調整map數的作用,減小max可以增加map數,增大max可以減少map數。需要提醒的是,直接調整mapred.map.tasks這個參數是沒有效果的。

調整大小的時機根據查詢的不同而不同,總的來講可以通過觀察map task的完成時間來確定是否需要增加map資源。如果map task的完成時間都是接近1分鐘,甚至幾分鐘了,那么往往增加map數量,使得每個map task處理的數據量減少,能夠讓map task更快完成;而如果map task的運行時間已經很少了,比如10-20秒,這個時候增加map不太可能讓map task更快完成,反而可能因為map需要的初始化時間反而讓job總體速度變慢,這個時候反而需要考慮是否可以把map的數量減少,這樣可以節省更多資源給其他Job。

Reduce階段的優化

這里說的reduce階段,是指前面流程圖中的reduce phase(實際的reduce計算)而非圖中整個reduce task。Reduce階段優化的主要工作也是選擇合適的reduce task數量,跟上面的map優化類似。

與map優化不同的是,reduce優化時,可以直接設置mapred.reduce.tasks參數從而直接指定reduce的個數。當然直接指定reduce個數雖然比較方便,但是不利于自動擴展。Reduce數的設置雖然相較map更靈活,但是也需要像map一樣設定一個自動生成規則,這樣運行定時job的時候就不用擔心原來設置的固定reduce數會由于數據量的變化而不合適。

Hive估算reduce數量的時候,使用的是下面的公式:

  1. num_reduce_tasks = min(${hive.exec.reducers.max}, 
  2. ${input.size} / ${ hive.exec.reducers.bytes.per.reducer})  

也就是說,根據輸入的數據量大小來決定reduce的個數,默認hive.exec.reducers. bytes.per.reducer為1G,而且reduce個數不能超過一個上限參數值,這個參數的默認取值為999。所以我們以調整hive.exec.reducers.bytes.per.reducer為主來設置reduce個數。

設置reduce數同樣也是根據運行時間作為參考調整,并且可以根據特定的業務需求、工作負載類型總結出經驗,所以不再贅述。

Map與Reduce之間的優化

所謂map和reduce之間,主要有3道工序。首先要把map輸出的結果進行排序后做成中間文件,其次這個中間文件就能分發到各個reduce,***reduce端在執行reduce phase之前把收集到的排序子文件合并成一個排序文件。

***個階段中,由于內存不夠,數據可能沒辦法在內存中一次性排序完成,那么就只能把局部排序的文件先保存到磁盤上,這個動作叫spill,然后spill出來的多個文件可以在***進行merge。如果發生spill,可以通過設置io.sort.mb來增大mapper輸出buffer的大小,避免spill的發生。另外合并時可以通過設置io.sort.factor來使得一次性能夠合并更多的數據。調試參數的時候,一個要看spill的時間成本,一個要看merge的時間成本,還需要注意不要撐爆內存(io.sort.mb是算在map的內存里面的)。Reduce端的merge也是一樣可以用io.sort.factor。一般情況下這兩個參數很少需要調整,除非很明確知道這個地方是瓶頸。

關于文件從map端copy到reduce端,默認情況下在5%的map完成的情況下reduce就開始啟動copy,這個有時候是很浪費資源的,因為reduce一旦啟動就被占用,一直等到map全部完成,收集到所有數據才可以進行后面的動作,所以我們可以等比較多的map完成之后再啟動reduce流程,這個比例可以通過mapred.reduce.slowstart. completed.maps去調整,他的默認值就是5%。如果覺得這么做會減慢reduce端copy的進度,可以把copy過程的線程增大。tasktracker.http.threads可以決定作為server端的map用于提供數據傳輸服務的線程,mapred.reduce.parallel.copies可以決定作為client端的reduce同時從map端拉取數據的并行度(一次同時從多少個map拉數據),修改參數的時候這兩個注意協調一下,server端能處理client端的請求即可。

文件格式的優化

文件格式方面有兩個問題,一個是給輸入和輸出選擇合適的文件格式,另一個則是小文件問題。小文件問題在目前的hive環境下已經得到了比較好的解決,hive的默認配置中就可以在小文件輸入時自動把多個文件合并給1個map處理(當然,如果能直接讀取大文件更好),輸出時如果文件很小也會進行一輪單獨的合并,所以這里就不專門討論了。相關的參數可以在這里找到。

關于文件格式,Hive中目前主要是3種,textfile,sequencefile和rcfile。總體上來說,rcfile的壓縮比例和查詢時間稍好一點,所以推薦使用。

關于使用方法,在建表結構時可以指定格式,然后指定壓縮插入:

  1. create table rc_file_test( col int ) stored as rcfile; 
  2. set hive.exec.compress.output = true
  3. insert overwrite table rc_file_test 
  4. select * from source_table;  

另外create table as select時也可以指定輸出格式,這個時候就要通過hive.default. fileformat來設定: 

  1. set hive.default.fileformat = SequenceFile; 
  2. set hive.exec.compress.output = true
  3. set mapred.output.compression.type = BLOCK; /*對于sequence file,壓縮方式有record和block兩種可選擇,block壓縮比更高*/ 
  4. insert overwrite table seq_file_test 
  5. select * from source_table;  

***要說的是,sequencefile和rcfile都是不支持空表要導入本地數據的,但是textfile格式的表可以支持文本在本地壓縮完成之后直接以壓縮格式導入,具體的做法可以看這里的詳細介紹。

Job整體優化

有一些問題必須從job的整體角度去觀察。這里討論幾個問題:Job執行模式(本地執行v.s.分布式執行)、索引、Join算法、以及數據傾斜。

Job執行模式

Hadoop的map reduce job可以有3種模式執行,即本地模式,偽分布式,還有真正的分布式。本地模式和偽分布式都是在最初學習hadoop的時候往往被說成是做單機開發的時候用到。但是實際上對于處理數據量非常小的job,直接啟動分布式job會消耗大量資源,而真正執行計算的時間反而非常少。這個時候就應該使用本地模式執行mr job,這樣執行的時候不會啟動分布式job,執行速度就會快很多。比如一般來說啟動分布式job,無論多小的數據量,執行時間一般不會少于20s,而使用本地mr模式,10秒左右就能出結果。

設置執行模式的主要參數有三個,一個是hive.exec.mode.local.auto,把他設為true就能夠自動開啟local mr模式。但是這還不足以啟動local mr,輸入的文件數量和數據量大小必須要控制,這兩個參數分別為hive.exec.mode.local.auto.tasks.max和hive.exec.mode.local.auto.inputbytes.max,默認值分別為4和128MB,即默認情況下,map處理的文件數不超過4個并且總大小小于128MB就啟用local mr模式。

索引

總體上來說,hive的索引目前還是一個不太適合使用的東西,這里只是考慮到敘述完整性,對其進行基本的介紹。

Hive中的索引架構開放了一個接口,允許你根據這個接口去實現自己的索引。目前hive自己有一個參考的索引實現(CompactIndex),后來在0.8版本中又加入位圖索引。這里就講講CompactIndex。

CompactIndex的實現原理類似一個lookup table,而非傳統數據庫中的B樹。如果你對table A的col1做了索引,索引文件本身就是一個table,這個table會有3列,分別是col1的枚舉值,每個值對應的數據文件位置,以及在這個文件位置中的偏移量。通過這種方式,可以減少你查詢的數據量(偏移量可以告訴你從哪個位置開始找,自然只需要定位到相應的block),起到減少資源消耗的作用。但是就其性能來說,并沒有很大的改善,很可能還不如構建索引需要花的時間。所以在集群資源充足的情況下,沒有太大必要考慮索引。

CompactIndex的還有一個缺點就是使用起來不友好,索引建完之后,使用之前還需要根據查詢條件做一個同樣剪裁才能使用,索引的內部結構完全暴露,而且還要花費額外的時間。具體看看下面的使用方法就了解了: 

  1. /*在index_test_table表的id字段上創建索引*/ 
  2. create index idx on table index_test_table(id)  
  3. as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' 
  4. with deferred rebuild; 
  5. alter index idx on index_test_table rebuild; 
  6.   
  7. /*索引的剪裁。找到上面建的索引表,根據你最終要用的查詢條件剪裁一下。如果你想跟RDBMS一樣建完索引就用,那是不行的,會直接報錯,這也是其麻煩的地方。*/ 
  8. create table my_index 
  9. as select `_bucketname`, `_offsets` 
  10. from default__index_test_table_idx__ where id = 10; 
  11.   
  12. /*現在可以用索引了,注意最終查詢條件跟上面的剪裁條件一致*/ 
  13. set hive.index.compact.file = /user/hive/warehouse/my_index; 
  14. set hive.input.format = org.apache.hadoop.hive.ql.index.compact.HiveCompactIndexInputFormat; 
  15. select count(*) from index_test_table where id = 10;  

Join算法

處理分布式join,一般有兩種方法。一種是replication join:把其中一個表復制到所有節點,這樣另一個表在每個節點上面的分片就可以跟這個完整的表join了;另一種方法是repartition join:把兩份數據按照join key進行hash重分布,讓每個節點處理hash值相同的join key數據,也就是做局部的join。這兩種方式在M/R Job中分別對應了map side join和reduce side join。在一些MPP DB中,數據可以按照某列字段預先進行hash分布,這樣在跟這個表以這個字段為join key進行join的時候,該表肯定不需要做數據重分布了,這種功能是以HDFS作為底層文件系統的hive所沒有的。

在默認情況下,hive的join策略是進行reduce side join。當兩個表中有一個是小表的時候,就可以考慮用map join了,因為小表復制的代價會好過大表shuffle的代價。使用map join的配置方法有兩種,一種直接在sql中寫hint,語法是/*+MAPJOIN (tbl)*/,其中tbl就是你想要做replication的表。另一種方法是設置hive.auto.convert.join = true,這樣hive會自動判斷當前的join操作是否合適做map join,主要是找join的兩個表中有沒有小表。至于多大的表算小表,則是由hive.smalltable.filesize決定,默認25MB。

但是有的時候,沒有一個表足夠小到能夠放進內存,但是還是想用map join怎么辦?這個時候就要用到bucket map join。其方法是兩個join表在join key上都做hash bucket,并且把你打算復制的那個(相對)小表的bucket數設置為大表的倍數。這樣數據就會按照join key做hash bucket。小表依然復制到所有節點,map join的時候,小表的每一組bucket加載成hashtable,與對應的一個大表bucket做局部join,這樣每次只需要加載部分hashtable就可以了。

然后在兩個表的join key都具有唯一性的時候(也就是可做主鍵),還可以進一步做sort merge bucket map join。做法還是兩邊要做hash bucket,而且每個bucket內部要進行排序。這樣一來當兩邊bucket要做局部join的時候,只需要用類似merge sort算法中的merge操作一樣把兩個bucket順序遍歷一遍即可完成,這樣甚至都不用把一個bucket完整的加載成hashtable,這對性能的提升會有很大幫助。

然后這里以一個完整的實驗說明這幾種join算法如何操作。

首先建表要帶上bucket:

  1. create table map_join_test(id int
  2. clustered by (id) sorted by (id) into 32 buckets 
  3. stored as textfile;  

然后插入我們準備好的800萬行數據,注意要強制劃分成bucket(也就是用reduce劃分hash值相同的數據到相同的文件):

  1. set hive.enforce.bucketing = true
  2. insert overwrite table map_join_test 
  3. select * from map_join_source_data;  

這樣這個表就有了800萬id值(且里面沒有重復值,所以可以做sort merge),占用80MB左右。

接下來我們就可以一一嘗試map join的算法了。首先是普通的map join:

  1. select /*+mapjoin(a) */count(*) 
  2. from map_join_test a 
  3. join map_join_test b on a.id = b.id;  

然后就會看到分發hash table的過程: 

  1. 2013-08-31 09:08:43     Starting to launch local task to process map join;      maximum memory = 1004929024 
  2. 2013-08-31 09:08:45     Processing rows:   200000  Hashtable size: 199999  Memory usage:   38823016        rate:   0.039 
  3. 2013-08-31 09:08:46     Processing rows:   300000  Hashtable size: 299999  Memory usage:   56166968        rate:   0.056 
  4. …… 
  5. …… 
  6. …… 
  7. 2013-08-31 09:12:39     Processing rows:  4900000 Hashtable size: 4899999 Memory usage:   896968104       rate:   0.893 
  8. 2013-08-31 09:12:47     Processing rows:  5000000 Hashtable size: 4999999 Memory usage:   922733048       rate:   0.918 
  9. Execution failed with exit status: 2 
  10. Obtaining error information 
  11.   
  12. Task failed! 
  13. Task ID: 
  14. Stage-4  

不幸的是,居然內存不夠了,直接做map join失敗了。但是80MB的大小為何用1G的heap size都放不下?觀察整個過程就會發現,平均一條記錄需要用到200字節的存儲空間,這個overhead太大了。不過這里我也搞不清楚hive為什么需要這么大空間,是否可以修改,總之對于map join的小表size一定要好好評估,如果有幾十萬記錄數就要小心了。

所以接下來我們就用bucket map join,之前分的bucket就派上用處了。只需要在上述sql的前面加上如下的設置:

  1. set hive.optimize.bucketmapjoin = true

然后還是會看到hash table分發: 

  1. 2013-08-31 09:20:39     Starting to launch local task to process map join;      maximum memory = 1004929024 
  2. 2013-08-31 09:20:41     Processing rows:   200000  Hashtable size: 199999  Memory usage:   38844832        rate:   0.039 
  3. 2013-08-31 09:20:42     Processing rows:   275567  Hashtable size: 275567  Memory usage:   51873632        rate:   0.052 
  4. 2013-08-31 09:20:42     Dump the hashtable into file: file:/tmp/hadoop/hive_2013-08-31_21-20-37_444_1135806892100127714/-local-10003/HashTable-Stage-1/MapJoin-a-10-000000_0.hashtable 
  5. 2013-08-31 09:20:46     Upload 1 File to: file:/tmp/hadoop/hive_2013-08-31_21-20-37_444_1135806892100127714/-local-10003/HashTable-Stage-1/MapJoin-a-10-000000_0.hashtable File size: 11022975 
  6. 2013-08-31 09:20:47     Processing rows:   300000  Hashtable size: 24432   Memory usage:   8470976 rate:   0.008 
  7. 2013-08-31 09:20:47     Processing rows:   400000  Hashtable size: 124432  Memory usage:   25368080        rate:   0.025 
  8. 2013-08-31 09:20:48     Processing rows:   500000  Hashtable size: 224432  Memory usage:   42968080        rate:   0.043 
  9. 2013-08-31 09:20:49     Processing rows:   551527  Hashtable size: 275960  Memory usage:   52022488        rate:   0.052 
  10. 2013-08-31 09:20:49     Dump the hashtable into file: file:/tmp/hadoop/hive_2013-08-31_21-20-37_444_1135806892100127714/-local-10003/HashTable-Stage-1/MapJoin-a-10-000001_0.hashtable 
  11. ……  

這次就會看到每次構建完一個hash table(也就是所對應的對應一個bucket),會把這個hash table寫入文件,重新構建新的hash table。這樣一來由于每個hash table的量比較小,也就不會有內存不足的問題,整個sql也能成功運行。不過光光是這個復制動作就要花去3分半的時間,所以如果整個job本來就花不了多少時間的,那這個時間就不可小視。

***我們試試sort merge bucket map join,在bucket map join的基礎上加上下面的設置即可:

  1. set hive.optimize.bucketmapjoin.sortedmerge = true
  2. set hive.input.format = org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;  

sort merge bucket map join是不會產生hash table復制的步驟的,直接開始做實際map端join操作了,數據在join的時候邊做邊讀。跳過復制的步驟,外加join算法的改進,使得sort merge bucket map join的效率要明顯好于bucket map join。

關于join的算法雖然有這么些選擇,但是個人覺得,對于日常使用,掌握默認的reduce join和普通的(無bucket)map join已經能解決大多數問題。如果小表不能完全放內存,但是小表相對大表的size量級差別也非常大的時候也可以試試bucket map join,不過其hash table分發的過程會浪費不少時間,需要評估下是否能夠比reduce join更高效。而sort merge bucket map join雖然性能不錯,但是把數據做成bucket本身也需要時間,另外其發動條件比較特殊,就是兩邊join key必須都唯一(很多介紹資料中都不提這一點。強調下必須都是唯一,哪怕只有一個表不唯一,出來的結果也是錯的)。這樣的場景相對比較少見,“用戶基本表 join 用戶擴展表”以及“用戶今天的數據快照 join 用戶昨天的數據快照”這類場景可能比較合適。

數據傾斜

所謂數據傾斜,說的是由于數據分布不均勻,個別值集中占據大部分數據量,加上hadoop的計算模式,導致計算資源不均勻引起性能下降。

還是拿博客網站的訪問日志說事吧。假設網站訪問日志中會記錄用戶的user_id,并且對于注冊用戶使用其用戶表的user_id,對于非注冊用戶使用一個user_id=0代表。那么鑒于大多數用戶是非注冊用戶(只看不寫),所以user_id=0占據了絕大多數。而如果進行計算的時候如果以user_id作為group by的維度或者是join key,那么個別reduce會收到比其他reduce多得多的數據——因為它要接收所有user_id=0的記錄進行處理,使得其處理效果會非常差,其他reduce都跑完很久了它還在運行。

group by造成的傾斜和join造成的傾斜需要分開看。group by造成的傾斜有兩個參數可以解決,一個是hive.map.aggr,默認值已經為true,意思是會做map端的combiner。所以如果你的group by查詢只是做count(*)的話,其實是看不出傾斜效果的,但是如果你做的是count(distinct),那么還是會看出一點傾斜效果。另一個參數是hive.groupby.skewindata。這個參數的意思是做reduce操作的時候,拿到的key并不是所有相同值給同一個reduce,而是隨機分發,然后reduce做聚合,做完之后再做一輪MR,拿前面聚合過的數據再算結果。所以這個參數其實跟hive.map.aggr做的是類似的事情,只是拿到reduce端來做,而且要額外啟動一輪job,所以其實不怎么推薦用,效果不明顯。

join造成的傾斜就比如上面描述的網站訪問日志和用戶表兩個表join:

  1. select a.* from logs a join users b on a.user_id = b.user_id; 

hive給出的解決方案是,把這種user_id = 0的特殊值先不在reduce端計算掉,而是先寫入hdfs,然后啟動一輪map join專門做這個特殊值的計算,期望能提高計算這部分值的處理速度。當然你要告訴hive這個join是個skew join,即set hive.optimize.skewjoin = true;還有要告訴hive如何判斷特殊值,根據hive.skewjoin.key設置的數量hive可以知道,比如默認值是100000,那么超過100000條記錄的值就是特殊值。

另外對于特殊值的處理往往跟業務有關系,所以也可以從業務角度重寫sql解決。比如前面這種傾斜join,可以把特殊值隔離開來(從業務角度說,users表應該不存在user_id = 0的情況,但是這里還是假設有這個值,使得這個寫法更加具有通用性): 

  1. select a.* from 
  2. select a.* 
  3. from (select * from logs where user_id = 0)  a 
  4. join (select * from users where user_id = 0) b 
  5. on a.user_id =  b.user_id 
  6. union all 
  7. select a.* 
  8. from logs a join users b 
  9. on a.user_id <> 0 and a.user_id = b.user_id 
  10. )t;  

SQL整體優化

前面對于單個job如何做優化已經做過詳細討論,但是hive查詢會生成多個job,針對多個job,有什么地方需要優化?

首先,在hive生成的多個job中,在有些情況下job之間是可以并行的,典型的就是子查詢。當需要執行多個子查詢union all或者join操作的時候,job間并行就可以使用了。比如下面的代碼就是一個可以并行的場景示意: 

  1. select * from 
  2. select count(*) from logs 
  3. where log_date = 20130801 and item_id = 1 
  4. union all 
  5. select count(*) from logs 
  6. where log_date = 20130802 and item_id = 2 
  7. union all 
  8. select count(*) from logs 
  9. where log_date = 20130803 and item_id = 3 
  10. ) t

設置job間并行的參數是hive.exec.parallel,將其設為true即可。默認的并行度***為8,也就是允許sql中8個job并行。如果想要更高的并行度,可以通過hive.exec.parallel. thread.number參數進行設置,但要避免設置過大而占用過多資源。

另外在實際開發過程中也發現,一些實現思路會導致生成多余的job而顯得不夠高效。比如這個需求:取出cnblog某一天訪問日志中同時看過博主“小張”和博主“小李”的人數。低效的思路是面向明細的,先取出看過博主“小張”的用戶,再取出看過博主“小李”的用戶,然后取交集,代碼如下: 

  1. select count(*) from 
  2. (select distinct user_id 
  3.  from cnblogs_visit_20130801 where blog_owner = ‘小張’) a 
  4. join 
  5. (select distinct user_id 
  6.  from cnblogs_visit_20130801 where blog_owner = ‘小李’) b 
  7. on a.user_id = b.user_id;  

這樣一來,就要產生2個求子查詢的job(當然,可以并行),一個join job,還有一個計算count的job。

但是我們直接用面向統計的方法去計算的話,則會更加符合M/R的模式: 

  1. select count(*) from 
  2.  select user_id, 
  3.  count(case when blog_owner = ‘小張’ then 1 endas visit_z, 
  4.  count(case when blog_owner = ‘小李’ then 1 endas visit_l 
  5.  from cnblogs_visit_20130801 group by user_id 
  6. ) t 
  7. where visit_z > 0 and visit_l > 0;  

這種實現方式轉換成job就只會有2個:內層的子查詢和外層的統計,更少的job也就帶來更高效的執行結果。

***種查詢方法符合思考問題的直覺,是工程師和分析師在實際查數據中***想到的寫法,然而想要更加快速的跑出結果,懂一點工具的內部機理,也是必須的。

【本文為51CTO專欄作者“王森豐”的原創稿件,轉載請注明出處】

責任編輯:龐桂玉 來源: 神算子
相關推薦

2013-03-20 16:23:53

數據清洗

2021-04-15 07:40:44

數據倉庫Hive環境搭建

2023-08-14 16:56:53

2018-03-15 08:50:46

Hive-數據存儲

2016-11-08 09:16:54

數據倉庫優化

2017-02-28 09:21:56

HadoopHive數據倉庫

2010-07-20 09:26:17

SQL Server

2023-12-13 07:26:24

數據湖倉數據倉庫性能

2022-06-24 09:38:43

數據庫大數據

2009-01-19 14:48:02

ETL優化過程原理

2021-09-01 10:03:44

數據倉庫云數據倉庫數據庫

2025-03-25 10:49:24

2016-08-15 12:57:01

數據倉庫索引架構維度索引

2009-01-20 14:22:49

ODS數據倉庫教程

2010-06-30 08:20:05

SQL Server

2023-10-08 16:26:23

數據倉庫

2017-05-16 10:23:51

數據倉庫拉鏈表

2009-02-25 08:56:26

數據倉庫SQL Server SQL Server

2009-02-24 12:14:27

微軟SQLServer20數據倉庫

2009-01-19 15:52:20

OracleOSFA數據倉庫
點贊
收藏

51CTO技術棧公眾號

成人在线丰满少妇av| 国产传媒在线观看| 国产精品一区二区无线| 久久久久久美女| 亚洲国产无码精品| 国产精品1区在线| 婷婷综合久久一区二区三区| 亚洲v国产v在线观看| 丁香六月天婷婷| 久久av中文字幕片| 日本免费在线精品| 久久综合综合久久| 日本一二区不卡| 日韩精品免费在线播放| 奇米视频7777| 日本免费久久| 亚洲成人福利片| 一区二区日本伦理| 亚洲欧美成人一区| 久久久久亚洲AV成人无在| 深夜福利一区二区三区| 欧美怡红院视频| www.av毛片| a视频在线观看免费| 国产区在线观看成人精品| 国产欧美日韩综合精品二区| 国产成人精品无码高潮| 日韩成人午夜电影| 日本精品免费观看| 国产无套粉嫩白浆内谢| 亚洲第一天堂| 日韩视频亚洲视频| 日韩视频在线观看免费视频| 色愁久久久久久| 精品国产91九色蝌蚪| 操人视频免费看| www久久久| 欧美日韩国产综合草草| 深夜黄色小视频| 久久天堂av| 日本电影亚洲天堂一区| 日本wwww视频| 26uuu亚洲电影| 激情成人在线视频| 777精品久无码人妻蜜桃| 成人在线免费观看黄色| 亚洲国产cao| 草b视频在线观看| 国产99re66在线视频| 一区二区三区在线观看动漫| 久久久久福利视频| 欧美人与禽性xxxxx杂性| 亚洲猫色日本管| www国产无套内射com| 免费黄色网页在线观看| 亚洲欧美色综合| 日本精品福利视频| 污污片在线免费视频| 亚洲一区在线免费观看| 国产 欧美 日韩 一区| 福利小视频在线| 红桃视频成人在线观看| 无码人妻丰满熟妇区毛片18| 精品免费av一区二区三区| 欧美亚洲一区二区在线| 亚洲精品免费一区亚洲精品免费精品一区| 日韩大陆av| 日韩欧美国产综合一区| 日本五十肥熟交尾| 宅男在线一区| 久久精品视频中文字幕| 欧美爱爱小视频| 亚洲每日更新| 国产精品高清网站| 国产又粗又长视频| 国产sm精品调教视频网站| 精品国产免费一区二区三区| www.黄在线观看| 亚洲蜜臀av乱码久久精品蜜桃| 免费cad大片在线观看| 成年男女免费视频网站不卡| 在线免费观看日本欧美| www.成年人| 欧美wwwwww| 色yeye香蕉凹凸一区二区av| 久久精品www| 日日摸夜夜添夜夜添亚洲女人| 国产欧美一区二区| 欧美特级特黄aaaaaa在线看| 欧美国产一区在线| 欧美一级免费在线观看| 欧美在线极品| 91精品国产一区二区三区| 久久福利小视频| 99视频精品视频高清免费| 国语自产精品视频在线看| 中文字幕欧美人妻精品| 成人丝袜18视频在线观看| 日韩欧美亚洲区| freexxx性亚洲精品| 欧美日韩精品一区二区三区四区| 东京热av一区| 久久综合国产| 欧美亚洲国产日韩2020| 国产视频一区二区三区四区五区| 2020日本不卡一区二区视频| 大陆极品少妇内射aaaaaa| 亚洲精品国产精品国产| 欧美岛国在线观看| 日本女人性生活视频| 99热这里只有成人精品国产| 亚洲在线免费看| 国产高清视频在线观看| 婷婷久久综合九色综合绿巨人| 免费精品99久久国产综合精品应用| 日韩三级视频| 欧美久久久精品| 97在线播放免费观看| 久久久久亚洲综合| 妞干网在线视频观看| 国产精品色婷婷在线观看| 一区二区成人av| 日本va欧美va国产激情| 国产成人丝袜美腿| 强开小嫩苞一区二区三区网站| 日韩经典一区| 一区二区欧美久久| 无码人妻精品一区二区| 91老师片黄在线观看| 妺妺窝人体色777777| 亚洲成人偷拍| 欧美成人免费在线观看| 国产精品欧美亚洲| 中文字幕一区日韩精品欧美| 色播五月激情五月| 久久影院一区| 国产噜噜噜噜噜久久久久久久久| 国产69精品久久app免费版| 日韩欧美在线字幕| 最新中文字幕视频| 国产亚洲高清视频| 久久手机视频| 正在播放日韩精品| 精品亚洲国产视频| 潘金莲一级淫片aaaaaa播放| 91免费观看视频| 中文字幕av在线一区二区三区| 国产精品久久久影院| 麻豆精品在线| 欧美精品生活片| 午夜精品久久久久久久96蜜桃| 亚洲免费观看高清完整版在线| 欧美色图校园春色| 好吊视频一区二区三区四区| 国产乱码精品一区二区三区卡| www在线看| 亚洲精品日韩在线| 黄色大全在线观看| 中文成人av在线| 欧美国产日韩另类| 国内精品亚洲| 蜜桃视频在线观看成人| 成人mm视频在线观看| 色青青草原桃花久久综合| 国产精品视频在线观看免费| 亚洲免费伊人电影| 国产69视频在线观看| 午夜一级久久| 一区二区精品在线| 99国产精品久久一区二区三区| 久久久久久国产| 青春草在线观看| 欧美少妇bbb| 欧美人与禽zozzo禽性配| 99久久免费精品| 欧美伦理片在线看| 欧美jizzhd精品欧美巨大免费| 国产精品二区三区| 成人不卡视频| 久久久久久12| 在线日本视频| 精品国产91乱码一区二区三区| 国产又粗又猛又黄视频| 亚洲免费观看高清完整版在线观看熊| 亚洲综合自拍网| 美腿丝袜亚洲综合| 欧美视频在线观看视频| 日本不卡高清| 国产精品美女久久久久av福利| 欧美舌奴丨vk视频| 欧美日韩国产成人| 国产高清免费在线播放| 日韩欧美国产一区二区三区| 久久永久免费视频| 亚洲精品视频在线| 一级片视频免费看| 粉嫩av亚洲一区二区图片| 狠狠热免费视频| 激情综合亚洲| 伊人婷婷久久| 国产精品日韩精品中文字幕| av一本久道久久波多野结衣| 成人福利一区二区| 57pao国产精品一区| wwwav在线| 这里只有精品丝袜| 手机福利在线| 精品成人a区在线观看| 一级黄色片在线看| 色婷婷av一区二区三区之一色屋| 国产精品18p| 亚洲欧美在线另类| 国产黄色大片免费看| www.久久精品| 欧美久久久久久久久久久| 麻豆极品一区二区三区| 免费日韩中文字幕| 最新成人av网站| 50度灰在线观看| 国产精品99久久| 日韩欧美三级一区二区| 深夜福利久久| 奇米888一区二区三区| 欧美xxxx在线| 精品国产免费一区二区三区 | 欧美特黄一区| 欧美h视频在线观看| 成人免费在线播放| 日韩高清三级| 欧美日韩123| 欧美日韩另类综合| 亚洲v天堂v手机在线| 好看的日韩精品视频在线| 成人台湾亚洲精品一区二区| 91嫩草国产在线观看| 国产一区二区av在线| 亚洲在线www| 欧美视频二区欧美影视| 99蜜桃在线观看免费视频网站| 国产一区二区三区亚洲综合| 91高跟黑色丝袜呻吟在线观看| 欧美第一在线视频| 亚洲va欧美va国产综合久久| 欧美a级大片在线| 亚洲a成v人在线观看| 国产精区一区二区| 成人免费观看网站| 精品精品国产毛片在线看| 精品国产乱码久久久久| 亚洲第一福利社区| 日韩免费av电影| 成人免费在线观看av| 一区中文字幕在线观看| 女人色偷偷aa久久天堂| 草草草视频在线观看| 日韩午夜在线| 日本熟妇人妻中出| 精品制服美女丁香| 亚洲av综合色区无码另类小说| 国产精品一区二区黑丝 | 久久久精品一品道一区| 日本欧美一区二区三区不卡视频| 国产精品久久久久久久裸模| 疯狂试爱三2浴室激情视频| 亚洲男人天堂av| 九九热在线视频播放| 91国偷自产一区二区三区成为亚洲经典| 中文字幕精品无码亚| 欧美一区二区黄| 天天操天天舔天天干| 亚洲性视频网站| 麻豆电影在线播放| 韩剧1988在线观看免费完整版| 色网在线免费观看| 国产综合在线观看视频| 国产精品白丝av嫩草影院| 日本高清视频一区二区三区| 91成人精品视频| 日本欧美黄色片| 免费亚洲电影在线| 91人妻一区二区| 国产日韩影视精品| 欧美xxxx黑人xyx性爽| 色素色在线综合| 成人av一区二区三区在线观看| 亚洲欧美日韩区| 中日韩高清电影网| 日本精品一区二区三区在线| 国产精品色婷婷在线观看| 久久综合九色综合久99| 亚洲精品2区| 四虎永久在线精品无码视频| 国产精品亚洲成人| 精品国产无码在线观看| 亚洲精品高清在线| 中文在线免费观看| 日韩成人激情视频| 成人福利网站| 国产精品国模在线| 久久a爱视频| 一区二区三区一级片| 米奇777在线欧美播放| 国产xxx在线观看| 最新中文字幕一区二区三区| 久久久精品福利| 日韩精品一区二区三区四区| av福利精品| 欧美中文字幕在线| 91亚洲无吗| 一级黄色录像免费看| 久久一综合视频| 在线观看国产三级| 亚洲综合另类小说| 国产男女无套免费网站| 在线成人中文字幕| 亚洲黄色中文字幕| 激情欧美一区二区三区中文字幕 | 日韩免费一级视频| 国产成人欧美日韩在线电影| 潘金莲一级黄色片| 欧美日韩色一区| 九一国产在线| 69影院欧美专区视频| 豆花视频一区二区| www.亚洲视频.com| 国产iv一区二区三区| 九九久久免费视频| 日韩女优毛片在线| 岛国中文字幕在线| 91免费国产网站| 婷婷激情图片久久| 在线免费看污网站| 日韩一区在线播放| 一区二区三区黄色片| 色哟哟亚洲精品一区二区| 婷婷激情一区| 视频三区二区一区| 奇米888四色在线精品| 天天躁日日躁aaaa视频| 在线一区二区观看| 国产剧情在线观看| 国产在线日韩在线| 91精品国产麻豆国产在线观看| 日本国产一级片| 一区二区三区四区激情| 亚洲国产中文字幕在线| 久久人人爽人人爽人人片av高请 | 五月天婷婷丁香| 日韩精品一区在线| 黄色在线观看www| 欧美日韩一区二| 日韩精彩视频在线观看| 手机看片国产日韩| 日韩一区二区在线看片| 欧洲一区二区三区| 国产综合第一页| 日韩电影一二三区| 91n在线视频| 亚洲精品一区二区三区影院 | 欧美丰满少妇人妻精品| 欧美日韩亚洲一区二区| 高清在线观看av| 成人黄色片在线| 韩国在线视频一区| 精品人妻少妇嫩草av无码| 欧美日韩高清一区二区三区| 青草在线视频| 久久草.com| 精品一区中文字幕| 国产无码精品在线播放| 国产一区二区三区18| 韩国三级大全久久网站| 亚洲理论电影在线观看| 国产欧美一区视频| 国产伦精品一区二区三区视频痴汉| 久久久久久成人精品| 精品美女在线视频| 成人三级做爰av| 日本电影亚洲天堂一区| 呦呦在线视频| 欧洲精品国产| 国产成人精品三级| 久久久免费高清视频| 久久精品国产亚洲精品2020| 久久中文字幕导航| 日本人视频jizz页码69| 亚洲午夜在线电影| 午夜国产福利在线| 精品国产一区二区三区四区精华| 久色婷婷小香蕉久久| 中文字幕一区二区三区精品| 日韩在线中文字| 日本成人7777| 麻豆传媒在线看| 欧美色网一区二区| 美女搞黄视频在线观看| 亚洲自拍偷拍一区二区三区| 国产偷国产偷精品高清尤物| 性生交大片免费看女人按摩| 国产在线高清精品|