ตัวเลือกใดมีประสิทธิภาพมากกว่า: เลือกจากเซิร์ฟเวอร์ที่เชื่อมโยงหรือแทรกลงในเซิร์ฟเวอร์ที่เชื่อมโยง


32

สมมติว่าฉันต้องส่งออกข้อมูลจากเซิร์ฟเวอร์หนึ่งไปยังเซิร์ฟเวอร์อื่น (ผ่านเซิร์ฟเวอร์ที่เชื่อมโยง) ข้อความใดจะมีประสิทธิภาพมากขึ้น

การดำเนินการในเซิร์ฟเวอร์ต้นทาง:

INSERT INTO [DestinationLinkedServer].[DestinationDB].[dbo].[Table]
SELECT a, b, c, ... FROM [dbo].Udf_GetExportData()

หรือดำเนินการในเซิร์ฟเวอร์เป้าหมาย:

INSERT INTO [dbo].[Table]
SELECT a, b, c, ...
FROM OPENQUERY([OriginLinkedServer],
    'SELECT a, b, c, ... FROM [OriginDB].[dbo].Udf_GetExportData()')

อันไหนจะเร็วกว่าและใช้ทรัพยากรน้อยลง (ทั้งเซิร์ฟเวอร์ต้นทางและเซิร์ฟเวอร์เป้าหมาย) เซิร์ฟเวอร์ทั้งสองเป็น SQL Server 2005

คำตอบ:


29

สมมติว่าฉันต้องส่งออกข้อมูลจากเซิร์ฟเวอร์หนึ่งไปยังเซิร์ฟเวอร์อื่น

ดีที่สุดคือการใช้

  • หากคุณต้องการให้ข้อมูลทั้งหมดใช้การสำรอง / กู้คืน BCP OUT & BCP IN หรือ SSIS
  • หากคุณต้องการชุดย่อยของข้อมูล (บางตารางเท่านั้น) ให้ใช้ SSIS หรือ BCP OUT & BCP IN

ในการย้ายข้อมูลขึ้นอยู่กับจำนวน / ขนาดของข้อมูลและแบนด์วิดธ์ n / w เซิร์ฟเวอร์ที่เชื่อมโยงจะฆ่าประสิทธิภาพ

การดำเนินการในเซิร์ฟเวอร์ต้นทางหรือดำเนินการในเซิร์ฟเวอร์เป้าหมาย - อันไหนจะเร็วกว่าและใช้ทรัพยากรน้อยกว่าทั้งหมด (ทั้งเซิร์ฟเวอร์ต้นทางและเซิร์ฟเวอร์เป้าหมาย)

- การดำเนินการในเซิร์ฟเวอร์ต้นทาง:

INSERT INTO [DestinationLinkedServer].[DestinationDB].[dbo].[Table]
SELECT a, b, c, ... FROM [dbo].Udf_GetExportData()

สิ่งนี้เรียกว่า PUSHING Data ในขณะที่คุณเรียกใช้งานแบบสอบถามบนเซิร์ฟเวอร์ต้นทางและส่งข้อมูลไปยังเซิร์ฟเวอร์ปลายทาง การดำเนินการนี้จะมีราคาแพง

--- ดำเนินการในเซิร์ฟเวอร์เป้าหมาย

INSERT INTO [dbo].[Table]
SELECT a, b, c, ...
FROM OPENQUERY([OriginLinkedServer],
    'SELECT a, b, c, ... FROM [OriginDB].[dbo].Udf_GetExportData()')

สิ่งนี้เรียกว่าการดึงข้อมูลในขณะที่คุณกำลังดำเนินการค้นหาบนเซิร์ฟเวอร์ปลายทางและดึงข้อมูลจากเซิร์ฟเวอร์ต้นทาง สิ่งนี้จะเร็วขึ้นมากและใช้ทรัพยากรน้อยลงเมื่อเทียบกับแบบเดิม (ขึ้นอยู่กับจำนวนข้อมูลที่ถูกดึง)

ในกรณีของวิธีการดึงการใช้ SQL Profiler คุณจะเห็นว่าคำสั่ง SQL เดียวถูกดำเนินการข้ามเซิร์ฟเวอร์ที่เชื่อมโยง (เซิร์ฟเวอร์ต้นทาง) และชุดผลลัพธ์ถูกดึงผ่านจากเซิร์ฟเวอร์ต้นทางไปยังเซิร์ฟเวอร์ปลายทางซึ่งเป็นการเพิ่มประสิทธิภาพที่เหนือกว่า PUSH วิธี.

อีกจุดที่ควรสังเกตคือ:

ระหว่างเซิร์ฟเวอร์ที่เชื่อมโยง (แบบแผนการตั้งชื่อ 4 ส่วนที่ใช้ servername.databasename.schema.tablename aka Distributed Queries) และ OPENQUERY โดยทั่วไป OPENQUERY จะรวดเร็ว ทำไม

สำหรับเซิร์ฟเวอร์ที่เชื่อมโยง - เครื่องมือเพิ่มประสิทธิภาพข้อความค้นหาสร้างแผนการดำเนินการโดยดูที่ระบบการตั้งชื่อแบบสอบถามและแบ่งออกเป็นแบบสอบถามระยะไกลและท้องถิ่น เคียวรีโลคัลถูกเรียกใช้งานแบบโลคัลและข้อมูลสำหรับเคียวรีแบบรีโมตถูกรวบรวมจากเซิร์ฟเวอร์รีโมตซึ่งถูกขัดแบบโลคัลรวมกันและนำเสนอให้กับผู้ใช้เป็นชุดระเบียนเดียว

สำหรับ OPENQUERY - เรียกใช้งานแบบสอบถามการส่งผ่านที่ระบุบนเซิร์ฟเวอร์ที่เชื่อมโยงที่ระบุ SQL Server ส่งแบบสอบถามแบบพาส - ทรูเป็นสายอักขระแบบสอบถามที่ไม่ตีความไปยังแหล่งข้อมูล OLE DB ดังนั้น SQL จะไม่ใช้ตรรกะใด ๆ กับเคียวรีและจะไม่พยายามประเมินว่าเคียวรีนั้นทำอะไรมันจะผ่านการสืบค้นที่ระบุไปยังเซิร์ฟเวอร์ที่เชื่อมโยงเป้าหมาย คิวรีแบบเปิดมีประโยชน์เมื่อคุณไม่ได้อ้างอิงหลายเซิร์ฟเวอร์ในคิวรีเดียว โดยทั่วไปแล้วรวดเร็วเนื่องจาก SQL ไม่แบ่งเป็นหลายการดำเนินการและไม่ดำเนินการใด ๆ กับเอาต์พุตที่ได้รับ

อ้างอิงการอ่านที่ดีเยี่ยม:


8

คุณวัดประสิทธิภาพอย่างไร อันไหนจะเร็วกว่ากัน? อันไหนจะกินทรัพยากรน้อยลงในเป้าหมาย? บนแหล่งที่มา? จำนวนแถวและประเภทข้อมูลประเภทใดที่มีคอลัมน์ในแถวเหล่านี้ คุณแน่ใจหรือไม่ว่าคุณสามารถใช้งาน TVF ผ่านเซิร์ฟเวอร์ที่เชื่อมโยง(เป็นเป้าหมายของ SQL 2008 หรือใหม่กว่า) ? คุณมั่นใจได้อย่างไรว่าการโยกย้ายข้อมูลนี้เป็นแบบ 1: 1 หากคุณดึงมาจาก TVF

ด้วยคำถามเหล่านั้นออกไป ...

อัปเดต 1

ดูเหมือนว่าคุณกำลังมองหา ETL (Extract-Transform-Load) ฉันขอแนะนำSSIS (SQL Server Integration Services)ซึ่งคุณสามารถดึงข้อมูลจากแหล่งข้อมูลใช้การแปลงที่คุณต้องการแล้วโหลดข้อมูลเหล่านั้นลงในเป้าหมายของคุณ ดูเหมือนว่ามันจะเป็นแพ็คเกจที่ค่อนข้างตรงไปตรงมา (ขึ้นอยู่กับการเปลี่ยนแปลง)


ภูมิปัญญาดั้งเดิมระบุว่าวิธีเซิร์ฟเวอร์ที่เชื่อมโยงจะออกไปที่ลิงค์ดึงข้อมูลไปยังเซิร์ฟเวอร์ภายในแล้วใช้ตรรกะใด ๆ (ตัวกรองเชื่อมต่อ ฯลฯ ) บนเซิร์ฟเวอร์ภายใน มีค่าใช้จ่ายในการดึงข้อมูลบนเซิร์ฟเวอร์ที่เชื่อมโยง แต่การประมวลผลส่วนใหญ่จะได้รับการจัดการในเครื่อง

วิธี OPENQUERY จะทำให้การประมวลผลบนเซิร์ฟเวอร์ระยะไกลและจะได้รับ "ผลการกรอง" โดยเซิร์ฟเวอร์ท้องถิ่น

ดูเหมือนว่าแม้ว่าคุณจะสามารถเรียกใช้ TVF ผ่านเซิร์ฟเวอร์ที่มีการเชื่อมโยงคุณจะได้รับผลที่เลวร้ายที่สุดของทั้งสองโลกประมวลผลจากระยะไกลและประมวลผลในพื้นที่

ขึ้นอยู่กับว่าคุณตัดสินใจจะก้าวไปข้างหน้าอย่างไรฉันก็จะมองOPENQUERYว่าเป็นวิธีหนึ่งในการนำเข้า / ส่งออกข้อมูลจำนวนมาก

ต้องบอกว่าทั้งหมดที่ ...

หากทั้งต้นทางและปลายทางที่ SQL Server (และเป้าหมายไม่ใช่รุ่นที่ต่ำกว่า) ทำไมไม่ทำการสำรองข้อมูลและกู้คืนข้อมูล นี่จะเป็นการย้ายข้อมูลที่แท้จริง นี่คือรหัสสำหรับคุณ

BACKUP DATABASE <DatabaseName, sysname, DatabaseName>
TO DISK=N'<backup_location, varchar, BackupLocation>.bak'
WITH INIT, FORMAT, COMPRESSION, COPY_ONLY

RESTORE DATABASE <NewDatabaseName, sysname, NewDatabaseName>
FROM DISK = N'<backup_location, varchar, BackupLocation>\
    <DatabaseName, sysname, DatabaseName>.bak'
WITH 
    MOVE '<DataFileName, sysname, DataFileName>' TO '<DataMDFPath, nvarchar(600), DataMDFPath>',
    MOVE '<LogFilePath, sysname, LogFilePath>' TO '<LogLDFPath, nvarchar(600), LogLDFPath>',
    REPLACE;

คุณสามารถอ้างถึงคำตอบนี้เกี่ยวกับวิธีการใช้แม่แบบใน SSMS

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.