แบ่งตารางออกเป็นรายการของตารางย่อย (List of Tables) โดยใช้ hash function กำหนดการกระจายข้อมูล
=Table.Partition(table as table, column as text, groups as number, hash as function) as list
=Table.Partition(table as table, column as text, groups as number, hash as function) as list
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| table | table | Yes | ตารางที่ต้องการแบ่ง | |
| column | text | Yes | ชื่อคอลัมน์ที่ใช้เป็นตัวกำหนด partition (ค่าของคอลัมน์นี้จะผ่านฟังก์ชัน hash) | |
| groups | number | Yes | จำนวนกลุ่ม (partition) ที่ต้องการ – ต้องเป็นจำนวนเต็มบวก | |
| hash | function | Yes | ฟังก์ชันสำหรับคำนวณค่า hash ปกติใช้ each _ (แทนค่าในคอลัมน์) หรือ each Text.Hash(_) สำหรับแฮชข้อความ |
แบ่งงานประมวลผล (Parallel Processing)
กระจายข้อมูลลงถัง (Bucketing)
เตรียมข้อมูลสำหรับการ Load เข้า Partitioned Table ใน Database
let Source = #table({"ID"}, {{1}, {2}, {3}, {4}, {5}, {6}}), Partitions = Table.Partition(Source, "ID", 2, each _) in Partitionslet
Source = #table({"ID"}, {{1}, {2}, {3}, {4}, {5}, {6}}),
Partitions = Table.Partition(Source, "ID", 2, each _)
in
Partitions
List containing 2 Tables: {Table1, Table2}
let Source = #table( {"Name"}, {{"Apple"}, {"Avocado"}, {"Banana"}, {"Blueberry"}, {"Cherry"}} ), Partitions = Table.Partition( Source, "Name", 2, each Characte…let
Source = #table(
{"Name"},
{{"Apple"}, {"Avocado"}, {"Banana"}, {"Blueberry"}, {"Cherry"}}
),
Partitions = Table.Partition(
Source,
"Name",
2,
each Character.ToNumber(Text.Start(_, 1)) mod 65
)
in
Partitions
List of 2 Tables
let Source = Table.FromRecords( List.Transform( List.Numbers(1, 1000), each [ID = _, Value = _ * 2] ) ), Batches = Table.Partition(Source, "ID", 5, each _) in B…let
Source = Table.FromRecords(
List.Transform(
List.Numbers(1, 1000),
each [ID = _, Value = _ * 2]
)
),
Batches = Table.Partition(Source, "ID", 5, each _)
in
Batches
List of 5 Tables (แต่ละตารางมี ~200 แถว)
let Source = #table( {"Email"}, {{"user1@example.com"}, {"user2@example.com"}, {"user3@example.com"}} ), Partitions = Table.Partition(Source, "Email", 3, each T…let
Source = #table(
{"Email"},
{{"user1@example.com"}, {"user2@example.com"}, {"user3@example.com"}}
),
Partitions = Table.Partition(Source, "Email", 3, each Text.Hash(_))
in
Partitions
List of 3 Tables
ไม่จำเป็น ผลการแบ่งขึ้นอยู่กับค่า hash ของข้อมูล ถ้าข้อมูลกระจายตัวดี ผลจะค่อนข้างเท่าๆ กัน แต่ถ้าข้อมูลเบ่งเบนไปทางค่าใดค่าหนึ่ง บางตารางอาจจะมีแถวมากกว่า
Table.Split แบ่งตามจำนวนแถว (เช่น ทุก 100 แถว) ส่วน Table.Partition แบ่งตามค่า hash ของคอลัมน์ที่กำหนด ใช้ได้กับข้อมูลที่ต้องกระจายแบบสม่ำเสมอ
สำหรับตัวเลข: each _ | สำหรับข้อความ: each Text.Hash(_) | สำหรับวันที่: each [Date.DayOfYear(_) * 1000] | ระบุ function ที่คืนค่าตัวเลขได้
จะได้รายการที่มี 1 ตารางเท่านั้น (ตารางต้นฉบับเหมือนเดิม) ไม่เหมาะที่จะ partition
ฟังก์ชัน Table.Partition ใช้สำหรับแบ่งตารางออกเป็นกลุ่มเล็กๆ (partitions) โดยคำนวณค่า hash จากคอลัมน์ที่กำหนด แล้วใช้ modulo เพื่อแบ่งแยกแถว ผลลัพธ์คือรายการของตารางย่อยหลายตาราง เหมาะสำหรับการกระจายข้อมูลขนาดใหญ่เพื่อประมวลผลแยกกัน หรือเตรียมข้อมูลสำหรับการประมวลผลแบบขนาน
เจ๋งเรื่องของ Table.Partition คือมันช่วยให้เราแบ่งข้อมูลขนาดใหญ่ได้อย่างชาญฉลาด โดยไม่ต้องเขียน loop หรือ filter ยุ่งๆ หากเรามีข้อมูลนับล้านแถวที่ต้องประมวลผลแยกหลายๆ เฟส Table.Partition จะจัดแบ่งให้เรียบร้อยตามค่า hash ซึ่งการกระจายจะค่อนข้างเท่าๆ กัน
ส่วนตัวผม Table.Partition มักใช้เวลาจัดเตรียมข้อมูลก่อนส่งไปยัง ETL ขั้นต่อไป หรือพอมีข้อมูลขนาดใหญ่ต้องประมวลผลทีละ batch ทีละกลุ่ม ผมจะใช้ Table.Partition มาแบ่งเป็นหลายๆ ตารางโดยอ้างอิงจากคอลัมน์สำคัญ 😎