Cái nào hiệu quả hơn: chọn từ máy chủ được liên kết hoặc chèn vào máy chủ được liên kết?


32

Giả sử tôi phải xuất dữ liệu từ máy chủ này sang máy chủ khác (thông qua các máy chủ được liên kết). Phát biểu nào sẽ hiệu quả hơn?

Thực thi trong máy chủ nguồn:

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

Hoặc thực thi trong máy chủ đích:

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

Cái nào sẽ nhanh hơn và tiêu thụ ít hơn các nguồn phục hồi trong tổng số (cả máy chủ nguồn và máy chủ đích)? Cả hai máy chủ đều là SQL Server 2005.

Câu trả lời:


29

Giả sử tôi phải xuất dữ liệu từ máy chủ này sang máy chủ khác.

Tốt nhất là sử dụng

  • NẾU bạn muốn tất cả dữ liệu sử dụng Sao lưu / Khôi phục; BCP OUT & BCP IN hoặc SSIS
  • NẾU bạn muốn tập hợp con dữ liệu (chỉ một số bảng) sử dụng SSIS hoặc BCP OUT & BCP IN

Để di chuyển dữ liệu, tùy thuộc vào số lượng / kích thước của dữ liệu và băng thông n / w, máy chủ được liên kết sẽ giết chết hiệu suất.

Thực thi trong máy chủ nguồn Hoặc thực thi trong máy chủ đích - Cái nào sẽ nhanh hơn và tiêu thụ ít nguồn lực hơn trong tổng số (cả máy chủ nguồn và máy chủ đích)?

- Thực thi trong máy chủ nguồn:

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

Đây được gọi là PUSHING Data khi bạn đang thực hiện truy vấn trên máy chủ nguồn và đẩy dữ liệu vào máy chủ đích. Đây sẽ là hoạt động đắt tiền.

--- thực thi trong máy chủ mục tiêu

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

Đây được gọi là Dữ liệu PULLING khi bạn đang thực hiện truy vấn trên máy chủ đích và lấy dữ liệu từ máy chủ nguồn. Điều này sẽ nhanh hơn rất nhiều và ít tốn tài nguyên hơn so với trước đây (tùy thuộc vào lượng dữ liệu được kéo).

Trong trường hợp của phương thức pull, sử dụng SQL Profiler, bạn sẽ thấy rằng một câu lệnh SQL duy nhất được thực thi trên máy chủ được liên kết (máy chủ nguồn) và tập kết quả được kéo từ máy chủ nguồn đến máy chủ đích, mức tăng hiệu suất rất lớn so với PUSH phương pháp.

Một điểm khác cần lưu ý là:

Giữa máy chủ được liên kết (quy ước đặt tên 4 phần được sử dụng servername.databasename.schema.tablename aka Phân phối truy vấn) và OPENQUERY, nói chung OPENQUERY sẽ nhanh. Tại sao ?

Đối với máy chủ được liên kết - Trình tối ưu hóa truy vấn tạo ra một kế hoạch thực hiện bằng cách xem danh pháp truy vấn và chia nó thành các truy vấn từ xa và cục bộ. Các truy vấn cục bộ được thực thi cục bộ và dữ liệu cho các truy vấn từ xa được thu thập từ các máy chủ từ xa, được lọc cục bộ, kết hợp với nhau và được trình bày cho người dùng cuối dưới dạng tập bản ghi duy nhất.

Đối với OPENQUERY - Thực hiện truy vấn chuyển qua được chỉ định trên máy chủ được liên kết đã chỉ định. SQL Server gửi các truy vấn chuyển qua dưới dạng các chuỗi truy vấn chưa được giải thích đến nguồn dữ liệu OLE DB. Do đó, SQL sẽ không áp dụng bất kỳ loại logic nào cho truy vấn và sẽ không cố ước tính truy vấn đó sẽ làm gì, nó chỉ đơn giản chuyển truy vấn đã chỉ định như máy chủ được liên kết đích. Các truy vấn mở rất hữu ích khi bạn không tham chiếu nhiều máy chủ trong một truy vấn. Nói chung là nhanh vì SQL không chia nó thành nhiều hoạt động và không thực hiện bất kỳ hành động cục bộ nào trên đầu ra nhận được.

Tài liệu tham khảo đọc tuyệt vời:


8

Làm thế nào bạn đo lường hiệu quả? Cái nào sẽ nhanh hơn? Cái nào sẽ tiêu thụ ít tài nguyên hơn trên mục tiêu? trên nguồn? Có bao nhiêu hàng và loại dữ liệu nào là các cột trong các hàng này? Bạn có chắc chắn có thể thực thi TVF thông qua một máy chủ được liên kết (là mục tiêu SQL 2008 trở lên không?) ? Làm thế nào để bạn đảm bảo di chuyển dữ liệu 1: 1 này nếu bạn lấy từ TVF?

Với những câu hỏi ngoài lề ...

Cập nhật 1

Có vẻ như bạn đang tìm kiếm ETL (Extract-Transform-Load). Tôi muốn giới thiệu SSIS (Dịch vụ tích hợp SQL Server) mà bạn có thể lấy dữ liệu từ nguồn, áp dụng các biến đổi mà bạn cần và sau đó tải chúng vào mục tiêu của mình. Điều này nghe có vẻ như là một gói khá đơn giản (tùy thuộc vào các biến đổi).


Sự khôn ngoan thông thường nói rằng cách tiếp cận máy chủ được liên kết sẽ đi ra liên kết, kéo dữ liệu đến máy chủ cục bộ và sau đó áp dụng bất kỳ logic nào (bộ lọc, tham gia, v.v.) trên máy chủ cục bộ. Có một số chi phí để lấy dữ liệu trên máy chủ được liên kết, nhưng phần lớn quá trình xử lý sẽ được xử lý cục bộ.

Phương thức OPENQUERY sẽ đưa quá trình xử lý lên máy chủ từ xa và "kết quả được lọc" sẽ được máy chủ cục bộ nhận.

Có vẻ như ngay cả khi bạn có thể thực thi TVF thông qua một máy chủ được liên kết, bạn sẽ trở nên tồi tệ nhất của cả hai thế giới, xử lý từ xa xử lý cục bộ (giả sử bạn có logic bổ sung để áp dụng cho tập hợp).

Tùy thuộc vào cách bạn quyết định tiến lên, tôi cũng sẽ xem xét OPENQUERYnhư một phương tiện để nhập / xuất dữ liệu hàng loạt.

Đã nói tất cả về điều đó ...

Nếu cả nguồn và đích tại SQL Server (và đích không phải là phiên bản thấp hơn), tại sao bạn không thực hiện sao lưu và khôi phục dữ liệu? Đây sẽ là một di chuyển dữ liệu thực sự. Đây là một số mã cho bạn.

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;

Bạn có thể tham khảo câu trả lời này về cách sử dụng các mẫu trong SSMS.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.