日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

循序漸進講解Oracle數(shù)據(jù)庫的Hash join

瀏覽:240日期:2023-11-28 10:40:36
在開發(fā)過程中,很多人經(jīng)常會使用到Hash Map或者Hash Set這種數(shù)據(jù)結構,這種數(shù)據(jù)結構的特點就是插入和訪問速度快。當向集合中加入一個對象時,會調用hash算法來獲得hash code,然后根據(jù)hash code分配存放位置。訪問的時,根據(jù)hashcode直接找到存放位置。

Oracle Hash join 是一種非常高效的join 算法,主要以CPU(hash計算)和內存空間(創(chuàng)建hash table)為代價獲得最大的效率。Hash join一般用于大表和小表之間的連接,我們將小表構建到內存中,稱為Hash cluster,大表稱為probe表。

效率

Hash join具有較高效率的兩個原因:

1.Hash 查詢,根據(jù)映射關系來查詢值,不需要遍歷整個數(shù)據(jù)結構。

2.Mem 訪問速度是Disk的萬倍以上。

理想化的Hash join的效率是接近對大表的單表選擇掃描的。

首先我們來比較一下,幾種join之間的效率,首先 optimizer會自動選擇使用hash join。

注意到Cost= 221

SQL> select * from vendition t,customer b WHERE t.customerid = b.customerid;

100000 rows selected.

Execution Plan

----------------------------------------------------------

Plan hash value: 3402771356

--------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 106K| 22M| 221 (3)| 00:00:03 |

|* 1 | HASH JOIN | | 106K| 22M| 221 (3)| 00:00:03 |

| 2 | TABLE ACCESS FULL| CUSTOMER | 5000 | 424K| 9 (0)| 00:00:01 |

| 3 | TABLE ACCESS FULL| VENDITION | 106K| 14M| 210 (2)| 00:00:03 |

--------------------------------------------------------------------------------

不使用hash,這時optimizer自動選擇了merge join。。

注意到Cost=3507大大的增加了。

SQL> select /*+ USE_MERGE (t b) */* from vendition t,customer b WHERE t.customerid = b.customerid;

100000 rows selected.

Execution Plan

----------------------------------------------------------

Plan hash value: 1076153206

-----------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time

-----------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 106K| 22M| | 3507 (1)| 00:00:43 |

| 1 | MERGE JOIN | | 106K| 22M| | 3507 (1)| 00:00:43 |

| 2 | SORT JOIN | | 5000 | 424K| | 10 (10)| 00:00:01 |

| 3 | TABLE ACCESS FULL| CUSTOMER | 5000 | 424K| | 9 (0)| 00:00:01 |

|* 4 | SORT JOIN | | 106K| 14M| 31M| 3496 (1)| 00:00:42 |

| 5 | TABLE ACCESS FULL| VENDITION | 106K| 14M| | 210 (2)| 00:00:03 |

-----------------------------------------------------------------------------------------

那么Nest loop呢,經(jīng)過漫長的等待后,發(fā)現(xiàn)Cost達到了驚人的828K,同時伴隨3814337 consistent gets(由于沒有建索引),可見在這個測試中,Nest loop是最低效的。在給customerid建立唯一索引后,減低到106K,但仍然是內存join的上千倍。

SQL> select /*+ USE_NL(t b) */* from vendition t,customer b WHERE t.customerid = b.customerid;

100000 rows selected.

Execution Plan

----------------------------------------------------------

Plan hash value: 2015764663

--------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 106K| 22M| 828K (2)| 02:45:41 |

| 1 | NESTED LOOPS | | 106K| 22M| 828K (2)| 02:45:41 |

| 2 | TABLE ACCESS FULL| VENDITION | 106K| 14M| 210 (2)| 00:00:03 |

|* 3 | TABLE ACCESS FULL| CUSTOMER | 1 | 87 | 8 (0)| 00:00:01 |

HASH的內部

HASH_AREA_SIZE在Oracle 9i 和以前,都是影響hash join性能的一個重要的參數(shù)。但是在10g發(fā)生了一些變化。Oracle不建議使用這個參數(shù),除非你是在MTS模式下。Oracle建議采用自動PGA管理(設置PGA_AGGREGATE_TARGET和WORKAREA_SIZE_POLICY)來,替代使用這個參數(shù)。由于我的測試環(huán)境是mts環(huán)境,自動內存管理,所以我在這里只討論mts下的hash join。

Mts的PGA中,只包含了一些棧空間信息,UGA則包含在large pool中,那么實際類似hash,sort,merge等操作都是有l(wèi)arge pool來分配空間,large pool同時也是auto管理的,它和SGA_TARGET有關。所以在這種條件下,內存的分配是很靈活。

Hash連接根據(jù)內存分配的大小,可以有三種不同的效果:

1.optimal 內存完全足夠

2.onepass 內存不能裝載完小表

3.multipass workarea executions 內存嚴重不足

下面,分別測試小表為50行,500行和5000行,內存的分配情況(內存都能完全轉載)。

Vendition表 10W條記錄

Customer表 5000

Customer_small 500,去Customer表前500行建立

Customer_pity 50,取Customer表前50行建立

表的統(tǒng)計信息如下:

SQL> SELECT s.table_name,S.BLOCKS,S.AVG_SPACE,S.NUM_ROWS,S.AVG_ROW_LEN,S.EMPTY_BLOCKS FROM user_tables S WHERE table_name IN ('CUSTOMER','VENDITION','CUSTOMER_SMALL','CUSTOMER_PITY') ;

TABLE_NAME BLOCKS AVG_SPACE NUM_ROWS AVG_ROW_LEN EMPTY_BLOCKS

CUSTOMER 35 1167 5000 38 5

CUSTOMER_PITY 4 6096 50 37 4

CUSTOMER_SMALL 6 1719 500 36 2

VENDITION 936 1021 100000 64 88打開10104事件追蹤:(hash 連接追蹤)

ALTER SYSTEM SET EVENTS ‘ 10104 TRACE NAME CONTEXT,LEVEL 2’;

測試SQL

SELECT * FROM vendition a,customer b WHERE a.customerid = b.customerid;

SELECT * FROM vendition a,customer_small b WHERE a.customerid = b.customerid;

SELECT * FROM vendition a,customer_pity b WHERE a.customerid = b.customerid;

小表50行時候的trace分析:

*** 2008-03-23 18:17:49.467

*** SESSION ID:(773.23969) 2008-03-23 18:17:49.467

kxhfInit(): enter

kxhfInit(): exit

*** RowSrcId: 1 HASH JOIN STATISTICS (INITIALIZATION) ***

Join Type: INNER join

Original hash-area size: 3883510

PS:hash area的大小,大約380k,本例中最大的表也不過250塊左右,所以內存完全可以完全裝載

Memory for slot table: 2826240

Calculated overhead for partitions and row/slot managers: 1057270

Hash-join fanout: 8

Number of partitions: 8

PS:hash 表數(shù)據(jù)連一個塊都沒裝滿,Oracle仍然對數(shù)據(jù)進行了分區(qū),這里和以前在一些文檔上看到的,當內存不足時才會對數(shù)據(jù)分區(qū)的說法,發(fā)生了變化。

Number of slots: 23

Multiblock IO: 15

Block size(KB): 8

Cluster (slot) size(KB): 120

PS:分區(qū)中全部行占有的cluster的size

Minimum number of bytes per block: 8160

Bit vector memory allocation(KB): 128

Per partition bit vector length(KB): 16

Maximum possible row length: 270

Estimated build size (KB): 0

Estimated Build Row Length (includes overhead): 45

# Immutable Flags:

Not BUFFER(execution) output of the join for PQ

Evaluate Left Input Row Vector

Evaluate Right Input Row Vector

# Mutable Flags:

IO sync

kxhfSetPhase: phase=BUILD

kxhfAddChunk: add chunk 0 (sz=32) to slot table

kxhfAddChunk: chunk 0 (lbs=0x2a97825c38, slotTab=0x2a97825e00) successfuly added

kxhfSetPhase: phase=PROBE_1

qerhjFetch: max build row length (mbl=44)

*** RowSrcId: 1 END OF HASH JOIN BUILD (PHASE 1) ***

Revised row length: 45

Revised build size: 2KB

kxhfResize(enter): resize to 12 slots (numAlloc=8, max=23)

kxhfResize(exit): resized to 12 slots (numAlloc=8, max=12)

Slot table resized: old=23 wanted=12 got=12 unload=0

*** RowSrcId: 1 HASH JOIN BUILD HASH TABLE (PHASE 1) ***

Total number of partitions: 8

Number of partitions which could fit in memory: 8

Number of partitions left in memory: 8

Total number of slots in in-memory partitions: 8

Total number of rows in in-memory partitions: 50

(used as preliminary number of buckets in hash table)

Estimated max # of build rows that can fit in avail memory: 66960

### Partition Distribution ###

Partition:0 rows:5 clusters:1 slots:1 kept=1

Partition:1 rows:6 clusters:1 slots:1 kept=1

Partition:2 rows:4 clusters:1 slots:1 kept=1

Partition:3 rows:9 clusters:1 slots:1 kept=1

Partition:4 rows:5 clusters:1 slots:1 kept=1

Partition:5 rows:9 clusters:1 slots:1 kept=1

Partition:6 rows:4 clusters:1 slots:1 kept=1

Partition:7 rows:8 clusters:1 slots:1 kept=1

PS:每個分區(qū)只有不到10行,這里有一個重要的參數(shù)Kept,1在內存中,0在磁盤

*** (continued) HASH JOIN BUILD HASH TABLE (PHASE 1) ***

PS:hash join的第一階段,但是要觀察更多的階段,需提高trace的level,這里略過

Revised number of hash buckets (after flushing): 50

Allocating new hash table.

*** (continued) HASH JOIN BUILD HASH TABLE (PHASE 1) ***

Requested size of hash table: 16

Actual size of hash table: 16

Number of buckets: 128

Match bit vector allocated: FALSE

kxhfResize(enter): resize to 14 slots (numAlloc=8, max=12)

kxhfResize(exit): resized to 14 slots (numAlloc=8, max=14)

freeze work area size to: 2359K (14 slots)

*** (continued) HASH JOIN BUILD HASH TABLE (PHASE 1) ***

Total number of rows (may have changed): 50

Number of in-memory partitions (may have changed): 8

Final number of hash buckets: 128

Size (in bytes) of hash table: 1024

kxhfIterate(end_iterate): numAlloc=8, maxSlots=14

*** (continued) HASH JOIN BUILD HASH TABLE (PHASE 1) ***

### Hash table ###

# NOTE: The calculated number of rows in non-empty buckets may be smaller

# than the true number.

Number of buckets with 0 rows: 86

Number of buckets with 1 rows: 37

Number of buckets with 2 rows: 5

Number of buckets with 3 rows: 0

PS:桶里面的行數(shù),最大的桶也只有2行,理論上,桶里面的行數(shù)越少,性能越佳。

Number of buckets with 4 rows: 0

Number of buckets with 5 rows: 0

Number of buckets with 6 rows: 0

Number of buckets with 7 rows: 0

Number of buckets with 8 rows: 0

Number of buckets with 9 rows: 0

Number of buckets with between 10 and 19 rows: 0

Number of buckets with between 20 and 29 rows: 0

Number of buckets with between 30 and 39 rows: 0

Number of buckets with between 40 and 49 rows: 0

Number of buckets with between 50 and 59 rows: 0

Number of buckets with between 60 and 69 rows: 0

Number of buckets with between 70 and 79 rows: 0

Nmber of buckets with between 80 and 89 rows: 0

Number of buckets with between 90 and 99 rows: 0

Number of buckets with 100 or more rows: 0

### Hash table overall statistics ###

Total buckets: 128 Empty buckets: 86 Non-empty buckets: 42

PS:創(chuàng)建了128個桶,Oracle 7開始的計算公式

Bucket數(shù)=0.8*hash_area_size/(hash_multiblock_io_count*db_block_size)

但是不準確,估計10g發(fā)生了變化。

Total number of rows: 50

Maximum number of rows in a bucket: 2

Average number of rows in non-empty buckets: 1.190476

小表500行時候的trace分析

Original hash-area size: 3925453

Memory for slot table: 2826240

。。。

Hash-join fanout: 8

Number of partitions: 8

。。。

### Partition Distribution ###

Partition:0 rows:52 clusters:1 slots:1 kept=1

Partition:1 rows:63 clusters:1 slots:1 kept=1

Partition:2 rows:55 clusters:1 slots:1 kept=1

Partition:3 rows:74 clusters:1 slots:1 kept=1

Partition:4 rows:66 clusters:1 slots:1 kept=1

Partition:5 rows:66 clusters:1 slots:1 kept=1

Partition:6 rows:54 clusters:1 slots:1 kept=1

Partition:7 rows:70 clusters:1 slots:1 kept=1

PS:每個partition的行數(shù)增加

。。。

Number of buckets with 0 rows: 622

Number of buckets with 1 rows: 319

Number of buckets with 2 rows: 71

Number of buckets with 3 rows: 10

Number of buckets with 4 rows: 2

Number of buckets with 5 rows: 0

。。。

### Hash table overall statistics ###

Total buckets: 1024 Empty buckets: 622 Non-empty buckets: 402

Total number of rows: 500

Maximum number of rows in a bucket: 4

Average number of rows in non-empty buckets: 1.243781

小表5000行時候的trace分析

Original hash-area size: 3809692

Memory for slot table: 2826240

。。。

Hash-join fanout: 8

Number of partitions: 8

Nuber of slots: 23

Multiblock IO: 15

Block size(KB): 8

Cluster (slot) size(KB): 120

Minimum number of bytes per block: 8160

Bit vector memory allocation(KB): 128

Per partition bit vector length(KB): 16

Maximum possible row length: 270

Estimated build size (KB): 0

。。。

### Partition Distribution ###

Partition:0 rows:588 clusters:1 slots:1 kept=1

Partition:1 rows:638 clusters:1 slots:1 kept=1

Partition:2 rows:621 clusters:1 slots:1 kept=1

Partiton:3 rows:651 clusters:1 slots:1 kept=1

Partition:4 rows:645 clusters:1 slots:1 kept=1

Partition:5 rows:611 clusters:1 slots:1 kept=1

Partitio:6 rows:590 clusters:1 slots:1 kept=1

Partition:7 rows:656 clusters:1 slots:1 kept=1

。。。

# than the true number.

Number of buckets with 0 rows: 4429

Number of buckets with 1 rows: 2762

Number of buckets with 2 rows: 794

Number of buckets with 3 rows: 182

Number of buckets with 4 rows: 23

Number of buckets with 5 rows: 2

Number of buckets with 6 rows: 0

。。。

### Hash table overall statistics ###

Total buckets: 8192 Empty buckets: 4429 Non-empty buckets: 3763

Total number of rows: 5000

Maximum number of rows in a bucket: 5

PS:當小表上升到5000行的時候,bucket的rows最大也不過5行。注意,如果bucket行數(shù)過多,遍歷帶來的開銷會帶來性能的嚴重下降。

Average number of rows in non-empty buckets: 1.328727

結論:

Oracle數(shù)據(jù)庫10g中,內存問題并不是干擾Hash join的首要問題,現(xiàn)今硬件價格越來越便宜,內存2G,8G,64G的環(huán)境也很常見。大家在針對hash join調優(yōu)的過程,更要偏重于partition和bucket的數(shù)據(jù)分配診斷。

日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
91精品视频一区二区| 91精品国产乱码久久久久久久| 国产精品免费精品自在线观看| 妖精视频成人观看www| 久久精品国产99| 国产麻豆一区| 亚洲美洲欧洲综合国产一区| 国产成人1区| 日韩av网站在线观看| 99国产精品99久久久久久粉嫩| 久久激情网站| 国产99精品| 国产精品蜜月aⅴ在线| 国产三级一区| 国产一卡不卡| 国产精品成人一区二区网站软件| 欧美亚洲在线日韩| 蜜桃av一区二区三区电影| 国产欧美在线观看免费| 久久精品伊人| 午夜精品影院| 免费人成精品欧美精品 | 欧美日韩精品一区二区三区视频 | 久久亚洲一区| 久久精品影视| 国产欧美日韩免费观看| 国产第一亚洲| 精品九九久久| 日韩精品不卡一区二区| 国产亚洲一区二区三区啪| 精品视频在线一区二区在线| 精品三级久久| 石原莉奈在线亚洲二区| 国产美女亚洲精品7777| 国产成人精品一区二区三区视频| 久久亚洲在线| 亚欧洲精品视频在线观看| 国产精品亚洲成在人线| 色在线视频观看| 久久国产精品久久久久久电车| 国产人成精品一区二区三| 日韩电影免费网址| 亚洲福利免费| 欧美日韩xxxx| 精品欧美激情在线观看| 久久99视频| 97se亚洲| 日韩不卡在线观看日韩不卡视频| 欧美69视频| 欧美精品九九| 最新国产拍偷乱拍精品| 亚洲一区欧美二区| 9色国产精品| 亚洲欧洲国产精品一区| 99在线精品免费视频九九视| 日韩视频久久| 一二三区精品| 蜜臀国产一区二区三区在线播放| 亚洲一区成人| 成人在线视频免费看| 久久不见久久见免费视频7| 婷婷精品久久久久久久久久不卡| 日韩免费小视频| 亚洲成人精品| 亚洲天堂日韩在线| 国产一区福利| 成人亚洲一区| 成人羞羞在线观看网站| 在线看片福利| 午夜在线播放视频欧美| 另类欧美日韩国产在线| 鲁大师成人一区二区三区| 国产成人a视频高清在线观看| 日韩精品一二区| 国产精品黄色| 亚洲一区日韩在线| 97久久亚洲| 日韩午夜精品| 日韩成人精品一区| 黄色亚洲大片免费在线观看| 欧洲精品一区二区三区| 国产精品一区二区三区www| 黄色在线观看www| 中文欧美日韩| 免费在线日韩av| 免费人成精品欧美精品| 99久久亚洲精品蜜臀| 老司机精品视频网| 日本亚州欧洲精品不卡| 国产精品7m凸凹视频分类| 欧美日韩尤物久久| 久久不见久久见中文字幕免费| 9色精品在线| 九色porny丨国产首页在线| 日韩精品一区二区三区中文在线 | 色婷婷综合网| 中文字幕系列一区| 欧美亚洲在线日韩| 日韩一区二区三区免费| 国产伦精品一区二区三区千人斩 | 亚洲人成精品久久久| 亚洲二区视频| 日韩精品专区| 91一区二区三区四区| 在线天堂中文资源最新版| 综合激情一区| 黄色精品网站| 三上悠亚国产精品一区二区三区| 日韩精品一级| 久久国产乱子精品免费女| 日韩在线观看一区| 国产精品一二| 国产精品yjizz视频网| 精品一区不卡| 精品91福利视频| 精品国产乱码久久久| 久久中文在线| 精品三级国产| 日韩一区二区三区免费| 久久理论电影| 日韩在线卡一卡二| 欧美亚洲综合视频| 91亚洲国产成人久久精品| 老司机精品在线| 日本大胆欧美人术艺术动态| 亚洲性视频h| 久久久噜噜噜| 国产精品15p| 日产午夜精品一线二线三线| 国产精品亚洲四区在线观看| 国产日韩欧美一区在线| 日本欧美一区二区在线观看| 日韩欧美三区| 欧美日本精品| 久久影院一区二区三区| 久久精品国产亚洲一区二区三区| 精品亚洲二区| 天堂中文av在线资源库| 国产专区精品| 亚洲欧美综合| 中文一区一区三区免费在线观| 日韩精品免费一区二区夜夜嗨| 7777精品| 国产aⅴ精品一区二区四区| 久久精品av| 国产欧美另类| 乱一区二区av| 综合激情一区| 婷婷综合六月| 日韩精品一区二区三区av | 国产欧美日韩精品一区二区免费 | 日本v片在线高清不卡在线观看| 久久激情av| 精品在线99| 精品国内亚洲2022精品成人| 午夜亚洲福利| 国产精品亚洲综合色区韩国| 国产精品一区二区美女视频免费看 | 手机精品视频在线观看| 国产视频一区欧美| 日本精品在线播放| 精品中文字幕一区二区三区| 九九精品调教| 日韩在线视频一区二区三区| 日韩精品视频一区二区三区| 日韩精品2区| 久久精品亚洲| 国产精品对白久久久久粗| 六月婷婷一区| 日韩中文av| 91亚洲精品在看在线观看高清| 欧美精品一区二区三区精品| 亚洲精品在线二区| 在线国产一区二区| 亚洲高清影视| 婷婷久久一区| 亚洲电影在线| 国产亚洲欧洲| 免费人成精品欧美精品| 视频一区中文| 伊人久久高清| 亚洲性色av| 伊伊综合在线| 久久国产电影| 蜜桃av一区二区| 欧美专区一区| 国产精品自在| 国产a久久精品一区二区三区| 久久婷婷一区| 欧美日一区二区在线观看| 国产另类在线| 蜜桃精品在线| 综合在线一区| 久久精品国产网站| 91日韩欧美| 日韩成人亚洲| 美女精品一区二区| 不卡福利视频| 日韩视频一区二区三区在线播放免费观看 | 视频一区中文字幕精品|