โหลดตารางเข้าสู่หน่วยความจำ (RAM) เพื่อแยกข้อมูลจากแหล่งเดิมและป้องกันไม่ให้ Query Folding ดึงข้อมูลใหม่
=Table.Buffer(table as table, optional options as nullable record) as table
=Table.Buffer(table as table, optional options as nullable record) as table
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| table | table | Yes | ตารางที่ต้องการ Buffer เข้าสู่หน่วยความจำ | |
| options | nullable record | Optional | BufferMode.Eager | เลือก BufferMode: BufferMode.Eager (โหลดทันที) หรือ BufferMode.Delayed (โหลดเมื่อต้องใช้) |
let Source = Excel.CurrentWorkbook(){[Name="Sales"]}[Content], Buffered = Table.Buffer(Source) in Bufferedlet
Source = Excel.CurrentWorkbook(){[Name="Sales"]}[Content],
Buffered = Table.Buffer(Source)
in
Buffered
ตารางเดิมแต่โหลดเข้า RAM เรียบร้อย
let Source = Table.FromRecords({ [ID = 1, Status = "Active", Amount = 1000], [ID = 2, Status = "Inactive", Amount = 2000], [ID = 3, Status = "Active", Amount =…let
Source = Table.FromRecords({
[ID = 1, Status = "Active", Amount = 1000],
[ID = 2, Status = "Inactive", Amount = 2000],
[ID = 3, Status = "Active", Amount = 1500]
}),
Buffered = Table.Buffer(Source),
Active = Table.SelectRows(Buffered, each [Status] = "Active"),
Inactive = Table.SelectRows(Buffered, each [Status] = "Inactive"),
HighAmount = Table.SelectRows(Buffered, each [Amount] > 1200)
in
Buffered
ตารางเดิม โดยข้อมูลดึงมาเพียงครั้งเดียว
let LargeTable = Sql.Database("Server", "MyDB"){[Item="Products"]}[Data], BufferedProducts = Table.Buffer(LargeTable), Orders = Excel.CurrentWorkbook(){[Name="O…let
LargeTable = Sql.Database("Server", "MyDB"){[Item="Products"]}[Data],
BufferedProducts = Table.Buffer(LargeTable),
Orders = Excel.CurrentWorkbook(){[Name="Orders"]}[Content],
JoinWithOrders = Table.NestedJoin(
Orders, "ProductID",
BufferedProducts, "ID",
"Product"
),
Returns = Excel.CurrentWorkbook(){[Name="Returns"]}[Content],
JoinWithReturns = Table.NestedJoin(
Returns, "ProductID",
BufferedProducts, "ID",
"Product"
)
in
JoinWithOrders
ตารางที่ Join กับ Products โดยข้อมูล Products โหลดมาเพียงครั้งเดียว
let Source = Sql.Database("Server", "MyDB"){[Item="MassiveTable"]}[Data], Buffered = Table.Buffer(Source, [BufferMode = BufferMode.Delayed]) in Bufferedlet
Source = Sql.Database("Server", "MyDB"){[Item="MassiveTable"]}[Data],
Buffered = Table.Buffer(Source, [BufferMode = BufferMode.Delayed])
in
Buffered
ตารางเดิม โดยจะโหลดเข้า Memory เมื่อต้องใช้ไม่ใช่ทันที
ไม่ใช่เสมอไป Buffer ช่วยเมื่อคุณใช้ตารางซ้ำหลายครั้ง ลดการดึงข้อมูลจากแหล่งเดิม แต่ถ้าใช้ตารางแค่ครั้งเดียว Buffer อาจทำให้ Performance แย่ลง เพราะต้องเสียเวลา + Memory ในการโหลด
Table.Buffer โหลดข้อมูลทั้งหมดเข้า Memory และป้องกัน Query Folding / Table.StopFolding เพียงป้องกัน Query Folding โดยไม่โหลดข้อมูล ถ้าต้องเพิ่ม Performance คุณควรเลือก Table.StopFolding อันดับแรก
ควร Buffer เมื่อ: (1) ใช้ตารางซ้ำ 2 ครั้งขึ้นไป (2) ตารางมาจาก Source ช้า เช่น SQL Database (3) ใช้ Join หรือ Merge ซ้ำกับตารางเดิม อย่า Buffer ถ้าใช้แค่ครั้งเดียว
Eager โหลดเข้า Memory ทันที (ค่าเริ่มต้น) / Delayed โหลดเมื่อต้องใช้จริง Delayed ช่วยประหยัด Memory ถ้าบางครั้งไม่ได้ใช้ตารางทั้งหมด
Table.Buffer ใช้เพื่อโหลดตารางเข้าสู่หน่วยความจำ (RAM) ซึ่งช่วยแยกข้อมูลจากแหล่งเดิมและป้องกันการดึงข้อมูลซ้ำในขั้นตอนถัดไป
ในทางปฏิบัติ Table.Buffer มีประโยชน์มากเมื่อคุณต้องใช้ตารางเดียวกันหลายครั้ง เช่นแบ่งข้อมูลเป็นหลาย Group หรือทำ Join กับตารางเดิมหลายครั้ง เพราะจะโหลดข้อมูลจากแหล่งเดิมเพียงครั้งเดียว
แต่ส่วนตัวผม Buffer ไม่ใช่วิธีแก้ปัญหาประสิทธิภาพแบบสากล นอกจากจะช่วยในกรณีที่ใช้ตารางซ้ำแล้ว Buffer อาจทำให้ Performance แย่ลง เพราะต้องโหลดข้อมูลทั้งหมดเข้า Memory ก่อน จึงควรใช้อย่างชาญฉลาด ไม่ใช่ใช้ให้ทั่ว 😎