Có cách nào để ngăn các UDF vô hướng trong các cột được tính toán ngăn chặn sự song song không?


29

Phần lớn đã được viết về sự nguy hiểm của UDF vô hướng trong SQL Server. Một tìm kiếm thông thường sẽ trả về vô số kết quả.

Tuy nhiên, có một số nơi mà UDF vô hướng là lựa chọn duy nhất.

Ví dụ: khi xử lý XML: XQuery không thể được sử dụng làm định nghĩa cột được tính toán. Một tùy chọn được Microsoft ghi lại là sử dụng UDF vô hướng để đóng gói XQuery của bạn trong UDF vô hướng, sau đó sử dụng nó trong một cột được tính toán.

Điều này có tác dụng khác nhau, và một số cách giải quyết.

  • Thực hiện từng hàng khi bảng được truy vấn
  • Buộc tất cả các truy vấn đối với bảng để chạy ser seri

Bạn có thể thực hiện xung quanh việc thực hiện từng hàng bằng cách lập sơ đồ hàm và duy trì cột được tính toán hoặc lập chỉ mục cho nó. Cả hai phương pháp này đều không thể ngăn chặn việc tuần tự hóa bắt buộc các truy vấn đập vào bảng, ngay cả khi UDF vô hướng không được tham chiếu.

Có một cách được biết để làm điều đó?

Câu trả lời:


31

nếu bạn:

  • đang chạy SQL Server 2014 trở lên; và
  • có thể chạy truy vấn với cờ theo dõi 176 hoạt động; và
  • cột được tính là PERSISTED

Cụ thể, ít nhất các phiên bản sau là bắt buộc :

  • Cập nhật tích lũy 2 cho SQL Server 2016 SP1
  • Cập nhật tích lũy 4 cho SQL Server 2016 RTM
  • Cập nhật tích lũy 6 cho SQL Server 2014 SP2

NHƯNG để tránh một lỗi (ref cho năm 2014 và cho năm 2016 và 2017 ) được giới thiệu trong các bản sửa lỗi đó, thay vào đó hãy áp dụng:

Cờ theo dõi có hiệu quả như một –Ttùy chọn khởi động , ở cả phạm vi toàn cầu và phiên sử dụng DBCC TRACEONvà mỗi truy vấn có OPTION (QUERYTRACEON)hoặc hướng dẫn kế hoạch.

Cờ dấu vết 176 ngăn chặn mở rộng cột tính toán bền bỉ.

Tải siêu dữ liệu ban đầu được thực hiện khi biên dịch một truy vấn mang đến tất cả các cột, không chỉ các cột được tham chiếu trực tiếp. Điều này làm cho tất cả các định nghĩa cột được tính toán có sẵn để khớp, thường là một điều tốt.

Là một tác dụng phụ đáng tiếc, nếu một trong các cột được tải (tính toán) sử dụng hàm do người dùng xác định vô hướng, thì sự hiện diện của nó sẽ vô hiệu hóa song song cho toàn bộ truy vấn, ngay cả khi cột được tính không thực sự được sử dụng .

Cờ theo dõi 176 giúp với điều này, nếu cột vẫn tồn tại, bằng cách không tải định nghĩa (vì mở rộng bị bỏ qua). Theo cách này, một hàm vô hướng do người dùng xác định không bao giờ xuất hiện trong cây truy vấn biên dịch, do đó tính song song không bị tắt.

Hạn chế chính của cờ theo dõi 176 (ngoài việc chỉ được ghi chép nhẹ) là nó cũng ngăn chặn biểu thức truy vấn khớp với các cột được tính toán bền vững: Nếu truy vấn chứa biểu thức khớp với cột được tính bền vững, cờ theo dõi 176 sẽ ngăn biểu thức được thay thế bởi một tham chiếu đến cột được tính toán.

Để biết thêm chi tiết, hãy xem bài viết SQLPerformance.com của tôi, Cột được tính toán đúng .

Do câu hỏi đề cập đến XML, như là một cách thay thế để thúc đẩy các giá trị bằng cách sử dụng hàm vô hướng và cột được tính toán, bạn cũng có thể xem xét bằng cách sử dụng Chỉ mục XML chọn lọc, như bạn đã viết trong Chỉ mục XML chọn lọc: Không tệ chút nào .


10

Ngoài @ tuyệt vời của Paul # 1 , có thực sự là một # 2 rằng:

  • hoạt động xa như SQL Server 2005,
  • không yêu cầu thiết lập cờ theo dõi,
  • không không đòi hỏi rằng cột tính toán được PERSISTED, và
  • (do không yêu cầu cờ theo dõi 176), không ngăn kết hợp biểu thức truy vấn với các cột được tính toán bền vững

Hạn chế duy nhất (theo như tôi có thể nói) là:

  • không hoạt động trên Cơ sở dữ liệu SQL Azure (ít nhất là chưa hoạt động, mặc dù nó hoạt động trên Amazon RDS SQL Server cũng như SQL Server trên Linux) và
  • là một chút bên ngoài vùng thoải mái của nhiều DBA

Và tùy chọn này là: SQLCLR

Đúng rồi. Một khía cạnh thú vị của các UDF vô hướng SQLCLR là, nếu chúng không thực hiện bất kỳ truy cập dữ liệu nào (không phải người dùng cũng như hệ thống), thì chúng không cấm song song. Và đó không chỉ là lý thuyết hay tiếp thị. Mặc dù tôi không có thời gian (hiện tại) để viết bài chi tiết đầy đủ, tôi đã thử nghiệm và chứng minh điều này.

Tôi đã sử dụng thiết lập ban đầu từ bài đăng trên blog sau (hy vọng OP không coi đây là nguồn không đáng tin cậy):

Quần jean ý tưởng tồi: Gợi ý nhiều chỉ số

Và thực hiện các xét nghiệm sau:

  1. Chạy truy vấn ban đầu như là ─⇾ Tính song song (như mong đợi)
  2. Đã thêm một cột được tính không cố định được xác định là ([c2] * [c3])⇾⇾ Tính song song (như mong đợi)
  3. Đã xóa cột được tính toán đó và thêm một cột được tính không tồn tại đã tham chiếu UDF vô hướng T-SQL (được tạo bằng SCHEMABINDING) được định nghĩa là RETURN (@First * @Second);─⇾ KHÔNG Song song (như mong đợi)
  4. Đã xóa cột được tính toán UDF T-SQL và thêm một cột được tính không kiên trì tham chiếu UDF vô hướng SQLCLR (đã thử với cả hai IsDeterministic = true= false) được định nghĩa là return SqlInt32.Multiply(First, Second);Parallelism (woo hoo !!)

Vì vậy, trong khi SQLCLR sẽ không hoạt động cho tất cả mọi người, nó chắc chắn có những lợi thế cho những người / tình huống / môi trường phù hợp. Và, vì nó liên quan đến câu hỏi cụ thể này - ví dụ được đưa ra khi sử dụng XQuery - nó sẽ hoạt động nhất định cho điều đó (và, tùy thuộc vào những gì cụ thể đang được thực hiện, thậm chí có thể nhanh hơn một chút).

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.