Teradata中join總結


Teradata join
1.SELECT Statement ANSI Join Syntax
版本V2R2以后,Teradata支持ANSI join語法及外連接:
SELECT colname [, colname , …]
FROM tabname [aname]
[INNER] JOIN
LEFT [OUTER] JOIN
RIGHT [OUTER] JOIN
FULL [OUTER] JOIN
CROSS JOIN
tabname1 [aname]
ON condition ;

INNER JOIN: 所有匹配的行.
LEFT OUTER JOIN: 以左邊表為准,右邊不能匹配的行填NULL.
RIGHT OUTER JOIN: 以右邊表為准,左邊不能匹配的行填NULL.
FULL OUTER JOIN : Both tables are used to qualify and extended with nulls.
CROSS JOIN : Product join or Cartesian product join.

2.Example of ANSI and Teradata JOIN Syntax
ANSI語法:
SELECT D.Department_Number AS "Dept Number"
,D.Department_Name AS "Dept Name"
,E.Last_Name AS "Last Name"
,E.Department_Number AS "Emp Dept"
FROM Department D
INNER JOIN Employee E
ON E.Department_Number = D.Department_Number;

Teradata語法:
SELECT D.Department_Number AS "Dept Number"
,D.Department_Name AS "Dept Name"
,E.Last_Name AS "Last Name"
,E.Department_Number AS "Emp Dept"
FROM Department D
,Employee E
WHERE E.Department_Number = D.Department_Number;
注:上述sql雖沒有明確定義為inner join,但Teradata解析器仍會將其解釋為inner join.

3.Join Processing
表與表之間的left outer join主要有以下形式:
– product join,
– merge join,
– hash join
– nest join
– exclusion join
而較常見的是product join和merge join。

做join的行必須在相同的AMP上:
如果需要,系統將創建一行或多行的spool拷貝並將其移動到公共AMP
連接處理從不移動或改變任何源表數據.

優化器基於以下原則選擇最好的join方式:
有用的索引
統計信息 (COLLECTed STATISTICS or Dynamic Sample)

四種join的區別可類似於兩數組的比較來解釋:
假定有A,B兩個數組,現在需要得到兩數組中的相同元素,有以下幾種方法:
算法1: A,B均先排序,再做比較
算法復雜度:o(nlogn)-------->Merge join
算法2: A,B均不排序,做比較
算法復雜度:o(n^2)-------->Product join
算法3: A排序,B不排序,B通過二分法做比較
算法復雜度介於前兩者之間------>Hash join
注:選擇merge join 還是product join主要是看比較時間長還是排序時間長.

4.Optimizer Minimizes Spool Usage
優化器利用以下方法將spool空間最小化:
僅投影(拷貝)查詢需要的列.
先做單表關聯(減少數據行).
只要可能,只將小表置於spool空間.

優化器在做join前將spool空間最小化:
Applies SET conditions first (WHERE).
Only the necessary columns are used in Spool.

5.Row Selection
只要可能,在join時加上行選擇條件
列投影永遠先於join,行選擇一般先於join.
技巧:減少參與join的行數可大大提升join效率.

6.Join Redistribution
兩表關聯,若被關聯的兩個字段均不為二表的PI,則需要做下列操作之一:
1>重新分布:將被關聯的字段設為PI,數據做重新分布;
2>小表復制:將小表的內容復制到一個AMP上,最終所有AMP均包含小表所有數據

兩表做Merge join時,有三種情況:
最好情況:參與join的列分別是兩表的PI,join操作可立刻執行.
-- 數據已經在相同的AMP上,不需要數據轉移到其他AMP上;
-- 數據行已經按照哈希排序存儲,不需要做排序操作.
次之:參與join的列有一個是表的PI,另一個不是.
-- 非PI表數據必須按照參與join的列值做hash重分布到目標AMP上;
-- 如果是小表,將全表復制到所有AMP上以便做join;
-- 如果表較大,將涉及到的行拷貝到目標AMP上.
糟糕情況:參與join的列均不是表的PI.
-- 兩個表將均依照join字段做重分布(或小表復制)

7.Duplicating a Table in Spool
對merge join,優化器可能選擇復制小表到每個AMP.
對product join,優化器總會復制一個表到所有AMP.
對以上兩種情況,每個AMP都必須要有足夠的空間以保證數據復制完成.

8.Merge Join
被關聯的數據行必須在相同AMP上:
Merge Join reads blocks from both tables only once.
Usually chosen for an equality join condition.
Generally more efficient than a product join.
Merge join步驟:
識別小表.
如果需要的話:
– Put qualifying data of one or both tables into spool(s).
– Move the spool rows to AMPs based on the join column hash.
– Sort the spool rows into join column hash sequence.
利用hash值做數據匹配.

9.嵌套關聯(Nested Joins)
一種特殊的關聯.
唯一的一種不會總是涉及到所有AMP的關聯.
從系統資源方面來說,這是最高效的一種方式.
OLTP應用的最好選擇.
優化器必須擁有以下信息才會選擇Nested Join:
-- 第一個表中(UPI或USI)的等值.
-- 第二個表中相對於索引具有唯一值的列.
系統從表1中得到唯一數據行.
利用hash值得到表2中匹配的數據行.
example:
SELECT E.Name,D.Name
FROM Employee E
INNER JOIN Department D
ON E.Dept = D.Dept
WHERE E.Enum = 5;

10.乘積join(Product Join)
下列情況均可產生product join:
The WHERE clause is missing.
A Join condition is not based on equality (<>, LESS THAN, GREATER THAN).
Join conditions are OR together.
There are too few Join conditions.
A referenced table is not named in any Join condition.
Table aliases are incorrectly used.
The Optimizer determines that it is less expensive than the other Join types.


Does not sort the rows.
May re-read blocks from one table if AMP memory size is exceeded.
It compares every qualifying Table1 row to every qualifying Table2 row.
Those that match the WHERE condition are saved in spool.
It is called a Product Join because:Total Compares = # Qualified Rows Table 1 * # Qualified Rows Table 2
The internal compares become very costly when there are more rows than AMP memory can hold at one time.
They are generally unintentional and often give meaningless output.
Product Join process:
-- Identify the Smaller Table and duplicate it in spool on all AMPs.
-- Join each spool row for Smaller Table to every row for Larger Table.

11.Cartesian Product
This is an unconstrained Product join.
Each row of Table1 is joined to every row in Table2.
Cartesian Product Joins consume significant system resources.
Cartesian Product Joins rarely have practical business use.
Cartesian Product Joins frequently occur when:
-- A join condition is missing or there are too few join conditions.
-- Join conditions are not based on equality.
-- A referenced table is not named in any join condition.
-- Table aliases are incorrectly used.
The transaction aborts if it exceeds the user’s spool limit.

12.Hash Join
Hash Join:小表依照row hash順序存儲,然后重分布或復制到所有的AMP.然后大表開始每行一條的處理數據,所以不需要將大表按照hash順序存儲.
可用以下DBS空值列來打開hash join和為hash join分配空間:
HTMemAlloc
SkewAllowance
優化技術可有效的將小表放入cache,然后將其與spool中未排序的大表做join.
Row Hash Join Process:
Identify the smaller table.
Redistribute or duplicate the smaller table in memory across the AMPs.
Sort the cache memory into join column row hash sequence.
Hold the rows in memory.
Use the join column row hash of the larger table to binary search memory for a match.
這類join避免大表排序,但有時會大表復制或重分布.

13.Exclusion Joins
返回無匹配記錄的行.
可能是merge或product join.
導致NOT IN字句和EXCEPT操作.
在可空列上使用3種邏輯值.
如果可能在建表時對可能出現NOT IN操作的列加上NOT NULL屬性.
說明: 在可空字段上做join時加上 WHERE colname IS NOT NULL 條件.

Exclusion Joins(NOT IN)的三條規則:
Any True – 濾掉
Any Unknown – 濾掉
All False – 保留.


14.(多表關聯)n-Table Joins
優化器一次只能處理處理兩個表.
join的結果再與第三個表做join.
所有的多表關聯都會被分解為兩表連接.
優化器自動嘗試決定最好的join順序.
收集關聯字段統計信息可以幫助優化器做好的選擇.

SELECT …. FROM Table_A, Table_B, Table_C, Table_D WHERE . . . ;


15.Join Considerations with PPI
PPI是基於Teardata已有應用的木塊擴展,因此,所有的join算法均支持PPI
同NPPI相比,用PPI時,如果在查詢約束中,大數目的分區沒有消除,Row Hash Merge Join的性能可能會比較糟.

原因:
同NPPI相比,PPI的Row Hash Merge Join算法比較復雜並且需要更多的資源(假設有效數據塊數目相等).
since rows are not in hash order, but rather in partition/hash order.

對兩個PPI不同的表做關聯,對一個PPI表和一個NPPI表做關聯,有以下三種方法:
One option is to spool the PPI table (or both PPI tables) into a non-PPI spool file in
preparation for a traditional merge join.
A second option (not always available) is to spool the non-PPI table (or one of the two PPI
tables) into a PPI spool file, with identical partitioning to the remaining table, in preparation
for a rowkey-based merge join.
The third approach is to use the sliding window join of the tables without spooling either one.
The optimizer will consider all reasonable join strategies, and pick the one that has the best-estimated performance.

NPPI與PPI做等值連接:
1)、分區較少的情況:
Teradata將保持NPPI表中的數據塊,PPI表中的數據每個分區一塊,以提高join性能.
即使沒有分區被消除,性能與NPPI表到NPPI表的連接相當(假定分區極少)
– 相同數目的磁盤I/O (排除非常規情況 - 一個hash值對應多個數據行)
– 內存需求高
– CPU利用稍高
– 如果加上分區限制,查詢效率將要高得多.

2)、分區較多的情況
Teradata保持NPPI表的塊,將PPI表的塊盡可能多的裝入內存,利用滾動窗口技術讓連接效率最佳
這類連接的效率一般NPPI到NPPI表的join要低,除非分區限制可以很大縮減工作量
-- 更多數目的磁盤I/O (NPPI表的數據塊必須重復掃描多次).
NPPI與PPI表join的I/O數目是:(p/k * d1) + d2
NPPI與NPPI表join的I/O數目是:d1 + d2
(說明: d1 = NPPI表的數據塊數目
d2 = PPI表的數據塊數目
p = 參與join的分區數目
k = PPI表可以加到內存中的分區數 )
-- 需要更多的內存
-- 需要更多的CPU資源
為了得到較好的性能,在查詢中盡量多的限制以消除最多的分區
-- p/k的值要盡量的小,即往內存中加入數據的次數盡量少
3)、滑動窗口
最直接的連接NPPI與PPI表的方法是將NPPI表與PPI表的逐個分區做關聯,也就是將整個關聯變化成一些列的子關聯.
這樣操作的效率可能較低,特別是NPPI表特別大時


16.Join Processing Summary
product join和merge join的概念
1)product join就是乘積關聯,做法是對左表的每一條記錄都跟右表的所有記錄進行關聯(即所說的笛卡爾積),然后根據關聯字段,篩出符合關聯條件的記錄。此法的缺點是作此關聯所付出的系統的CPU和IO代價較大(由於笛卡爾積的關系) 但相對與merge join來說它的優點是左表和右表都不需要排序,因此teradata優化器只在右表記錄數和導出字段字節數乘積較小的情況下(一般憑經驗,記錄數小於25條以下,字段字節數沒測過)或者關聯條件包含非等式關聯或者關聯條件中帶有OR時才選擇product join;
2)merge join就是合並關聯,做法是對左右表分別進行排序,然后根據關聯條件進行匹配關聯。其優點時每一個左表記錄只會跟右表的一條或某幾條記錄進行關聯,大大減少了CPU和IO的花費,但缺點是對於右表記錄數較少的情況下,對非常大的左表進行排序較浪費數據庫資源。總的說來,merge join是一種有較高效率的關聯算法,因此teradata優化器一般情況下都采用merge join,只在右表記錄數和導出字段字節數乘積較小的情況下采用product join

重分布還是全拷貝
由於teradata數據庫是一種分布式並行數據庫,記錄是根據特定字段的值通過哈西計算后分布在多個AMP上,因此要實現關聯運算,除了采用何種關聯算法(即采用product join還是merge join,還是。。。)的問題,還有左表和右表如何分布到多個AMP上的問題。一般情況下表是根據PI值做分布,但是關聯時不是。
1)對於右表記錄數較少的情況下,teradata優化器會將右表的記錄在每一個AMP上都復制一份,也就是說如果數據庫有50AMP,10條記錄的表經過拷貝后在數據庫中就有500記錄,此種做法就是全拷貝。可以想象此種做法同product join一樣,在右表記錄數較多情況下,比較浪費系統的IO資源和SPOOL空間,但是它也有好處,好處是它能夠避免左表的重分布(下面提到的概念)。
2)如果右表是分區導出表,teradata優化器除了主索引關聯的情況下,無法如何總是采用全拷貝的方法分布右表.
3)如果右表記錄數較多,同時不是分區導出表的情況下,teradata優化器會將左右表根據關聯字段重新計算HASH值,然后根據HASH值做AMP的分布,即關聯字段替代了PI成為SPOOL空間中關聯表的主索引.此法就叫做重分布.其優點是減低了系統的IO資源和SPOOL的空間的使用(表記錄數在重分布前后不變),但缺點是由於重分布,導致了節點間的數據移動和bynet的負荷增大,同時導致了AMP數據分布的不平均。

多關聯SQL
對於一個左表(主表)同多個右表(維表,關聯表)關聯時,teradata總是一個一個的關聯,即先拿左表同右表1關聯生成新的左表,然后再拿新的左表同右表2關聯生成新的左表,如此反復,直到右表都關聯完畢。此法的效率相當有問題。當左表較大,而右表較小的情況,每做一次關聯,就要進行哈希重分布或全拷貝,同時還進行一次表的全掃描,資源浪費較大。

關於優化的一些建議
1)對於左表極大而右表的記錄數較少的情況下,建議通過使用導出分區表強制teradata優化器使用全拷貝,避免了左表的重分布和數據分布不均勻
2)對於右表極大但是又是分區導出表的情況下,建議采用無分區的臨時表,先將分區導出表插入到臨時表,通過左表和臨時表進行關聯,以避免teradata優化器使用全拷貝的方式
3)多於多關聯SQL,可以建立臨時表,先將多個很小的右表通過笛卡爾積形成大表(注意控制大表條數,一般控制在千萬級效果較佳),然后再將左表同關聯好的右表進行關聯。

teradata對於表級的left outer join的SQL優化
一般說來:表與表之間的left outer join主要有四種形式:product join,merge join,hash join和nest join 而較常見的是product join和merge join。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM