ขนาดแบทช์ที่แนะนำสำหรับSqlBulkCopy
อะไร? ฉันกำลังมองหาสูตรทั่วไปที่สามารถใช้เป็นจุดเริ่มต้นในการปรับแต่งประสิทธิภาพได้
ขนาดแบทช์ที่แนะนำสำหรับSqlBulkCopy
อะไร? ฉันกำลังมองหาสูตรทั่วไปที่สามารถใช้เป็นจุดเริ่มต้นในการปรับแต่งประสิทธิภาพได้
คำตอบ:
ฉันมียูทิลิตี้นำเข้าซึ่งนั่งอยู่บนเซิร์ฟเวอร์จริงเดียวกันกับอินสแตนซ์ SQL Server ของฉัน การใช้แบบกำหนดเองIDataReader
จะแยกวิเคราะห์ไฟล์แบบแบนและแทรกลงในฐานข้อมูลโดยใช้SQLBulkCopy
. ไฟล์ทั่วไปมีแถวที่มีคุณสมบัติประมาณ 6 ล้านแถวโดยเฉลี่ย 5 คอลัมน์ของทศนิยมและข้อความสั้น ๆ ประมาณ 30 ไบต์ต่อแถว
จากสถานการณ์นี้ฉันพบว่าขนาดแบตช์ 5,000 จะเป็นการประนีประนอมความเร็วและการใช้หน่วยความจำที่ดีที่สุด ฉันเริ่มต้นด้วย 500 และทดลองกับขนาดใหญ่ขึ้น ฉันพบว่า 5,000 เร็วขึ้น 2.5 เท่าโดยเฉลี่ยมากกว่า 500 การแทรก 6 ล้านแถวใช้เวลาประมาณ 30 วินาทีโดยมีขนาดชุด 5,000 และประมาณ 80 วินาทีโดยมีขนาดแบตช์ 500
10,000 ไม่ได้เร็วขึ้นอย่างวัดได้ การย้ายขึ้นไป 50,000 ทำให้ความเร็วเพิ่มขึ้นสองสามเปอร์เซ็นต์ แต่ก็ไม่คุ้มกับภาระที่เพิ่มขึ้นบนเซิร์ฟเวอร์ มากกว่า 50,000 แสดงว่าไม่มีการปรับปรุงความเร็ว
นี่ไม่ใช่สูตร แต่เป็นจุดข้อมูลอื่นให้คุณใช้
นี่เป็นปัญหาที่ฉันใช้เวลาในการตรวจสอบ ฉันต้องการเพิ่มประสิทธิภาพการนำเข้าไฟล์ CSV ขนาดใหญ่ (16+ GB, 65+ ล้านระเบียนและเพิ่มขึ้นเรื่อย ๆ ) ไปยังฐานข้อมูล SQL Server 2005 โดยใช้แอปพลิเคชันคอนโซล C # (.Net 2.0) ดังที่Jeremyได้ชี้ให้เห็นแล้วคุณจะต้องทำการปรับแต่งบางอย่างสำหรับสถานการณ์เฉพาะของคุณ แต่ฉันขอแนะนำให้คุณมีขนาดแบทช์เริ่มต้นที่ 500 และทดสอบค่าทั้งด้านบนและด้านล่างนี้
ฉันได้รับคำแนะนำให้ทดสอบค่าระหว่าง 100 ถึง 1,000 สำหรับขนาดแบทช์จากโพสต์ฟอรัม MSDNนี้และไม่เชื่อ แต่เมื่อฉันทดสอบขนาดแบทช์ระหว่าง 100 ถึง 10,000 ฉันพบว่า 500 เป็นค่าที่เหมาะสมที่สุดสำหรับแอปพลิเคชันของฉัน 500 คุ้มค่าสำหรับSqlBulkCopy.BatchSize
ยังแนะนำที่นี่
เพื่อเพิ่มประสิทธิภาพการดำเนินงานต่อไป SqlBulkCopy ของคุณตรวจสอบนี้คำแนะนำ MSDN ; ฉันพบว่าการใช้ SqlBulkCopyOptions.TableLock ช่วยลดเวลาในการโหลด
ตามที่คนอื่นระบุไว้ขึ้นอยู่กับสภาพแวดล้อมของคุณโดยเฉพาะปริมาณแถวและเวลาแฝงของเครือข่าย
โดยส่วนตัวแล้วฉันจะเริ่มต้นด้วยการตั้งค่าBatchSize
คุณสมบัติเป็น 1,000 แถวและดูว่ามีประสิทธิภาพอย่างไร ถ้ามันใช้งานได้ฉันจะเพิ่มจำนวนแถวเป็นสองเท่า (เช่นเป็น 2000, 4000 เป็นต้น) จนกว่าฉันจะหมดเวลา
มิฉะนั้นหากหมดเวลาที่ 1,000 ฉันจะลดจำนวนแถวลงครึ่งหนึ่ง (เช่น 500) จนกว่าจะได้ผล
ในแต่ละกรณีฉันจะเพิ่มเป็นสองเท่า (ถ้าสำเร็จ) หรือลดลงครึ่งหนึ่ง (ถ้าล้มเหลว) ความแตกต่างระหว่างขนาดแบทช์ที่พยายามสองครั้งล่าสุดจนกว่าจะพบจุดที่น่าสนใจ
ปัจจัยอื่น ๆ ที่ต้องพิจารณาคือการคัดลอกแถวชุดเดียวใช้เวลานานเท่าใด การหมดเวลาจะเกิดขึ้นหากชุดแถวที่คัดลอกเกินBulkCopyTimeout
คุณสมบัติซึ่งโดยค่าเริ่มต้นคือ 30 วินาที คุณอาจลองเพิ่มBulkCopyTimeout
คุณสมบัติเป็นสองเท่าเป็น60 วินาที ซึ่งจะช่วยให้สามารถคัดลอกแถวแบตช์ชุดใหญ่ได้นานขึ้น ตัวอย่างเช่นชุดแถว 50,000 แถวอาจใช้เวลาประมาณ 40 วินาทีหากเกินเวลาที่กำหนด 30 วินาทีดังนั้นการชนกันนานถึง 60 วินาทีอาจช่วยในเรื่องประสิทธิภาพ
ทั้งหมดนี้ขึ้นอยู่กับการใช้งานของคุณ
คุณคาดหวังความเร็วระดับใดบนเครือข่ายของคุณ คุณกำลังใช้มันในฟอร์มหรือ ASP.Net? คุณต้องการแจ้งเตือนผู้ใช้ถึงความคืบหน้าหรือไม่? ขนาดของงานทั้งหมดคืออะไร?
จากประสบการณ์ของฉันที่เรียกใช้สำเนาจำนวนมากโดยไม่ระบุขนาดชุดงานจะทำให้เกิดปัญหาการหมดเวลา ฉันชอบเริ่มต้นด้วยบางอย่างเช่นบันทึก 1,000 รายการและทำการปรับเปลี่ยนบางอย่างจากที่นั่น
ฉันลองหลายขนาดแล้วในกรณีของฉัน 5000 นั้นดี