Các vấn đề về hiệu năng SQL với truy vấn từ xa trên máy chủ được liên kết


8

Sproc này

create proc dbo.Get_Accounts as
begin
  declare @current_date datetime
  set @current_date = dbo.fn_currdate()

  select [fields]
  into dbo.current_accounts
  from linkedserver.database.dbo.accounts
  where date = @current_date
end

liên tục thất bại sau 10 phút với thông báo lỗi sau:

Máy chủ: Msg 7399, Cấp 16, Trạng thái 1, Dòng 1 Nhà cung cấp OLE DB 'SQLOLEDB' đã báo cáo lỗi. Việc thực thi bị chấm dứt bởi nhà cung cấp vì đã đạt đến giới hạn tài nguyên. [Thông báo trả về của nhà cung cấp OLE / DB: Hết thời gian hết hạn] Theo dõi lỗi OLE DB [ICOLandB 'ICommandText'

Tuy nhiên, khi tôi chạy cùng một truy vấn từ cùng một cơ sở dữ liệu (không phải từ xa) trong cửa sổ truy vấn tương tác có ngày được mã hóa cứng:

  select [fields]
  into dbo.current_accounts
  from linkedserver.database.dbo.accounts
  where date = '1/20/2012'

Nó trở lại sau 30 giây.

Máy chủ cục bộ là SQLSERVER 2008, từ xa là SQLSERVER 2000.

Chúng tôi đã làm như sau nhưng không có kết quả:

  • Tái tạo các lưu trữ Proc.
  • sp_recompile trên Proc được lưu trữ
  • cập nhật số liệu thống kê trên dbo.accounts
  • bỏ và tạo lại các chỉ mục trên dbo.accounts
  • bỏ chỉ mục trên dbo.accounts và thử
  • DBCC FREEPROCCACHE & DBCC DROPCLEANBUFFERS trên cả máy chủ cục bộ và máy chủ từ xa
  • Khởi động lại máy chủ từ xa (không phải là một tùy chọn dễ dàng trên máy chủ cục bộ)

Câu hỏi

  • Bất cứ ai có thể giải thích hành vi kỳ lạ này?
  • Bất kỳ đề xuất về các lựa chọn khác để sửa nó?

Câu trả lời:


11

Bạn có thể bật dấu vết cờ 7300có thể cung cấp cho bạn một thông báo lỗi chi tiết hơn

Có bao nhiêu hàng một truy vấn đại diện trả về? Làm thế nào nhanh chóng / đáng tin cậy là kết nối mạng giữa hai máy chủ?

Có thể một bộ dữ liệu lớn đang mất quá nhiều thời gian để chuyển (trên thời gian truy vấn thực tế). Bạn có thể tăng giá trị thời gian chờ.

Bạn có thể thử cấu hình lại cài đặt thời gian chờ như sau:

Đặt thời gian chờ đăng nhập từ xa thành 300 giây:

sp_configure 'remote login timeout', 300
go 
reconfigure with override 
go 

Đặt thời gian chờ truy vấn từ xa thành 0 (chờ vô hạn):

sp_configure 'remote query timeout', 0 
go 
reconfigure with override 
go 

Cập nhật : SQL Server 2012 SP1 trở đi : người dùng có SELECTquyền sẽ có thể truy cập DBCC SHOW_STATISTICS, điều này sẽ cải thiện hiệu suất chỉ đọc trên các máy chủ được liên kết. Tham chiếu: https://msdn.microsoft.com/en-us/l Library / ms174384 (v = sql.110) .aspx

Cập nhật : Bạn đã đúng khi nói rằng đó không phải là kích thước của dữ liệu hoặc tốc độ kết nối. Nó rung chuông trong ký ức đầy sương mù của tôi và tôi nhớ nơi tôi đã thấy nó: Chậm trong Ứng dụng, Nhanh trong SSMS? (Một vấn đề với máy chủ được liên kết). Đây không phải là thông số đánh hơi, chính số liệu thống kê bị thiếu (do quyền), khiến kế hoạch truy vấn xấu được sử dụng:

Bạn có thể thấy rằng các ước tính là khác nhau. Khi tôi chạy dưới dạng sysadmin, ước tính là 1 hàng, đó là một số chính xác, vì không có Đơn hàng nào ở Northwind mà ID đơn hàng vượt quá 20000. Nhưng khi tôi chạy như một người dùng đơn giản, ước tính là 249 hàng. Chúng tôi nhận ra con số cụ thể này là 30% trong số 830 đơn đặt hàng hoặc ước tính cho hoạt động bất bình đẳng khi trình tối ưu hóa không có thông tin. Trước đây, điều này là do một giá trị biến không xác định, nhưng trong trường hợp này không có biến nào có thể được biết. Không, đó là số liệu thống kê bị thiếu.

Miễn là truy vấn chỉ truy cập các bảng trong máy chủ cục bộ, trình tối ưu hóa luôn có thể truy cập số liệu thống kê cho tất cả các bảng trong truy vấn; không có kiểm tra cho phép thêm. Nhưng điều này khác với các bảng trên một máy chủ được liên kết. Khi SQL Server truy cập vào một máy chủ được liên kết, không có giao thức bí mật nào chỉ được sử dụng cho liên lạc giữa các máy chủ. Không, thay vào đó, SQL Server sử dụng giao diện OLE DB tiêu chuẩn cho các máy chủ được liên kết, là các phiên bản SQL Server khác, Oracle, tệp văn bản hoặc nguồn dữ liệu được ủ tại nhà của bạn và kết nối giống như bất kỳ người dùng nào khác. Chính xác làm thế nào để lấy số liệu thống kê phụ thuộc vào nguồn dữ liệu và nhà cung cấp OLE DB được đề cập. Trong trường hợp này, nhà cung cấp là SQL Server Native Client, truy xuất số liệu thống kê theo hai bước. (Bạn có thể thấy điều này bằng cách chạy Profiler với máy chủ từ xa). Đầu tiên, nhà cung cấp chạy thủ tục sp_table_statistic2_rowset để trả về thông tin về số liệu thống kê cột nào, cũng như thông tin về mật độ và thông tin mật độ của họ. Trong bước thứ hai, nhà cung cấp chạy DBCC SHOW_STATISTICS, một lệnh trả về số liệu thống kê phân phối đầy đủ. (Chúng ta sẽ xem xét kỹ hơn về lệnh này sau trong bài viết này.) Đây là cách bắt: để chạy DBCC SHOW_STATISTICS, bạn phải là thành viên của vai trò máy chủ sysadmin hoặc bất kỳ vai trò cơ sở dữ liệu nào db_owner hoặc db_ddladmin.

Và đây là lý do tại sao tôi nhận được kết quả khác nhau. Khi chạy dưới dạng sysadmin, tôi đã nhận được số liệu thống kê phân phối đầy đủ cho biết rằng không có hàng nào có ID đơn hàng> 20000 và ước tính là một hàng. (Nhắc lại rằng trình tối ưu hóa không bao giờ giả sử các hàng bằng 0 từ thống kê.) Nhưng khi chạy với tư cách là người dùng đơn giản, DBCC SHOW_STATISTICS đã thất bại với lỗi cấp phép. Lỗi này không được lan truyền, nhưng thay vào đó, trình tối ưu hóa chấp nhận rằng không có số liệu thống kê và sử dụng các giả định mặc định. Vì nó đã nhận được thông tin về cardinality, nó đã học được rằng bảng từ xa có 830 hàng, ước tính khoảng 249 hàng.

Bất cứ khi nào bạn gặp phải vấn đề về hiệu năng trong đó một truy vấn bao gồm quyền truy cập vào máy chủ được liên kết bị chậm trong ứng dụng, nhưng nó chạy nhanh khi bạn kiểm tra nó từ SSMS, bạn phải luôn luôn điều tra nếu không đủ quyền trên cơ sở dữ liệu từ xa. (Hãy nhớ rằng quyền truy cập vào máy chủ được liên kết có thể không bị truy cập trong truy vấn, nhưng có thể bị ẩn trong chế độ xem.) Nếu bạn xác định rằng các quyền trên cơ sở dữ liệu từ xa là vấn đề, bạn có thể thực hiện hành động nào?

  • Bạn có thể thêm người dùng vào vai trò db_ddladmin, nhưng vì điều này cho phép họ thêm và thả bảng, nên điều này không được khuyến khích.

  • Theo mặc định, khi người dùng kết nối với máy chủ từ xa, họ sẽ tự kết nối, nhưng bạn có thể thiết lập ánh xạ đăng nhập với sp_addlinkedsrvlogin, để người dùng ánh xạ tới tài khoản proxy có tư cách thành viên trong db_ddladmin. Lưu ý rằng tài khoản proxy này phải là thông tin đăng nhập SQL, vì vậy đây không phải là tùy chọn nếu máy chủ từ xa không bật xác thực SQL. Giải pháp này cũng hơi mơ hồ từ góc độ bảo mật, mặc dù nó tốt hơn đề xuất trước đó.

  • Trong một số trường hợp, bạn có thể viết lại truy vấn bằng OPENQUERY để buộc đánh giá trên máy chủ từ xa. Điều này có thể đặc biệt hữu ích, nếu truy vấn bao gồm một số bảng từ xa. (Nhưng nó cũng có thể phản tác dụng, bởi vì trình tối ưu hóa bây giờ thậm chí còn nhận được ít thông tin thống kê hơn từ máy chủ từ xa.)

  • Tất nhiên bạn có thể sử dụng pin đầy đủ các gợi ý và hướng dẫn kế hoạch để có được kế hoạch bạn muốn.

  • Cuối cùng, bạn nên tự hỏi liệu có cần truy cập máy chủ được liên kết không. Có lẽ các cơ sở dữ liệu có thể trên cùng một máy chủ? Dữ liệu có thể được nhân rộng? Một số giải pháp khác?


Nó trả về khoảng 140k hồ sơ. nhưng vì nó chỉ hoạt động tốt khi giá trị ngày được mã hóa cứng nên tôi không thể nghĩ ra vấn đề I / O hoặc mạng sẽ ảnh hưởng đến phiên bản được tham số hóa vô cùng. Ruột của tôi nói rằng truy vấn đang được chuyển đến máy chủ từ xa và trình tối ưu hóa từ xa bằng cách nào đó chọn một kế hoạch truy vấn xấu khi nó không thể hiểu ý nghĩa của tham số. Nhưng reindexing và purging cache / buff nên sửa điều đó (tôi giả sử). Tôi sẽ xem xét thời gian chờ để xem liệu chúng tôi có thể làm cho nó ít nhất trở lại không. Cảm ơn

1
Câu trả lời tuyệt vời và giải thích chính xác vấn đề tôi đang gặp phải, cảm ơn. Tôi sẽ nói thêm rằng theo MSDN , từ SQL2012 SP1 trở đi, người dùng có SELECTquyền sẽ có thể truy cập DBCC SHOW_STATISTICS, điều này sẽ cải thiện hiệu suất chỉ đọc trên các máy chủ được liên kết mà không phải ảnh hưởng đến bảo mật.
Steve Pettifer

2

Điều gì xảy ra khi bạn thử điều này (nghĩa là chỉ rõ ràng những gì nên chạy trên máy chủ từ xa)?:

select [fields]
into dbo.current_accounts
from OPENQUERY(linkedserver, 'SELECT [fields] FROM database.dbo.accounts where date = ''1/20/2012''');

Tôi nghi ngờ trong trường hợp của bạn ở trên SQL Server chỉ là kéo toàn bộ bảng từ máy chủ từ xa rồi chạy truy vấn cục bộ (tôi đã thấy điều này xảy ra nhiều lần trong quá khứ). Tôi thích rõ ràng hơn (bằng cách sử dụng OPENQUERY hoặc bằng cách tạo SP trên máy chủ từ xa) để không có cơ hội nhầm lẫn.


1

Vì đây là sự cố về nguồn, bộ nhớ ngoài máy chủ SQL được sử dụng để tải trình điều khiển bên ngoài và CLR có thể gần với giới hạn của nó. Mặc định là 256MB. Để giải quyết vấn đề này, tôi khuyên bạn nên truy cập trình quản lý cấu hình máy chủ SQL, tab nâng cao và thêm tùy chọn -g vào cuối tham số khởi động.ie; -g1024 sau đó khởi động lại dịch vụ SQL Server. Tôi thường làm điều này khi chúng tôi sử dụng một số lượng lớn máy chủ được liên kết. http://msdn.microsoft.com/en-us/l Library / ms190737.aspx


1

Tôi có hai ý tưởng có thể giúp ích. Tôi cũng sẽ nói với bạn rằng tôi đã gặp xui xẻo với hiệu năng chạy truy vấn đối với các máy chủ được liên kết. Vì vậy, khuyến nghị đầu tiên của tôi là tránh nó nếu bạn có thể.

Ý tưởng đầu tiên của tôi là cài đặt thủ tục được lưu trữ vào hộp SQL Server 2000, để nó tham chiếu đến máy chủ cục bộ. Sau đó bạn có thể thực hiện các thủ tục được lưu trữ từ xa.

exec linkedserver.database.dbo.Get_Accounts

Nếu bạn có thể đi theo con đường này, nó sẽ cải thiện hiệu suất rất nhiều.

Ý tưởng thứ hai của tôi là có được kế hoạch truy vấn ước tính khi chạy thủ tục được lưu trữ. Có phải nó cho bạn thấy những gì đang mất rất nhiều thời gian? Một vấn đề tiềm ẩn là tài khoản bạn đang sử dụng trên máy chủ được liên kết có thể không có đủ quyền để lấy số liệu thống kê của bảng (bạn cần nhiều quyền hơn cho máy chủ được liên kết so với máy chủ cục bộ). Và điều đó có thể làm cho các truy vấn chậm không thể tin được. Bạn có thể đọc thêm về vấn đề cụ thể ở đây .

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.