2010-01-26 24 views
16

Tôi đã sử dụng thủ tục CLR lưu trữ trong máy chủ SQL trong một thời gian, nhưng tôi vẫn tự hỏi những tình huống tốt nhất để sử dụng chúng là gì.Các vấn đề tốt để giải quyết bằng cách sử dụng các procs được lưu trữ CLR là gì?

MSDN cung cấp một số nguyên tắc để sử dụng như thao tác chuỗi nặng (regex), hoặc thay thế T-SQL khai báo rất nhiều biến bảng và con trỏ. Tôi tò mò muốn biết những vấn đề SO người dùng đang giải quyết với CLR lưu trữ procs, và ví dụ/điểm chuẩn là tốt. Ví dụ, tôi đã tìm thấy CLR lưu trữ procs + SSRS là một cách tuyệt vời để có được logic thao tác dữ liệu ra khỏi SSRS và ra khỏi T-SQL, và vào mã được quản lý dễ đọc và thao tác hơn.

Trả lời

23

Nhiều vấn đề đòi hỏi denormalization và/hoặc các hoạt động tuần tự có thể được xử lý đặc biệt tốt bởi CLR và có thể được sử dụng để cải thiện hiệu suất đáng kể mà không bị mất khả năng sử dụng ở đầu SQL (nhiều). Thay vì dựa hoàn toàn vào các hoạt động dựa trên bộ hoặc lặp lại, bạn có thể sử dụng phương pháp lai, sử dụng giải pháp dựa trên tập cho các đường lớn và chuyển sang mô hình lặp lại cho các vòng lặp chặt chẽ.

Các kiểu được xây dựng trong hierarchyid và không gian địa lý (tức là geography) trong SQL Server 2008 là ví dụ hay về vấn đề không chuẩn hóa. Cả hai đều chứa một lượng lớn dữ liệu rất khó chuẩn hóa mà không làm tổn thương hiệu suất - bạn sẽ cần sử dụng đệ quy hoặc con trỏ để thực hiện bất kỳ công việc có ý nghĩa nào với chúng, hoặc sử dụng tổ kích hoạt và/hoặc tác vụ theo lịch duy trì một bảng không chuẩn hóa.

Một vấn đề khác mà tôi đã giải quyết với các loại CLR là nén nội tuyến. Điều này nghe có vẻ giống như một bài tập vô nghĩa hoặc học tập, nhưng khi dữ liệu được chuẩn hóa hoàn toàn của bạn đang đẩy vào terabyte, thì kích thước giảm 80-90% có nghĩa là rất nhiều. SQL có sẵn tính năng nén tích hợp sẵn và SQL 2005 có vardecimal, và đó cũng là những công cụ tốt, nhưng thuật toán "giảm thiểu" miền có thể hiệu quả gấp đôi về tốc độ nén và CPU. Rõ ràng điều này không áp dụng cho mọi vấn đề, nhưng nó áp dụng cho một số vấn đề.

Tuy nhiên, một vấn đề rất phổ biến khác thường thấy trên trang web này là tạo ra một chuỗi trên bay - ví dụ một chuỗi các ngày liên tiếp.Các giải pháp phổ biến là CTE đệ quy, các bảng tuần tự tĩnh và các bảng spt_values ít được biết đến, nhưng một UDF CLR đơn giản hoạt động tốt hơn bất kỳ bảng nào và mang lại sự linh hoạt hơn nhiều.

Cuối cùng trong danh sách của tôi: Tập hợp luồng trực tuyến do người dùng xác định cũng rất hữu ích, đặc biệt cho bất kỳ điều gì có liên quan đến thống kê. Có một số điều bạn chỉ đơn giản là không thể soạn thảo trong tổng hợp SQL dựng sẵn, chẳng hạn như trung bình, trung bình di chuyển trọng số, vv UDA cũng có thể lấy nhiều đối số để bạn có thể tham số hóa chúng; về mặt kỹ thuật, tổng hợp không được đảm bảo nhận dữ liệu theo bất kỳ thứ tự cụ thể nào trong phiên bản SQL Server hiện tại, nhưng bạn có thể vượt qua giới hạn đó bằng cách cho nó một đối số bổ sung và sử dụng nó để thực hiện bất kỳ chức năng cửa sổ nào (có tổng hợp nhổ ra một UDT mà sau đó có thể được chuyển thành một bảng).

Nó thực sự rất bực bội như thế nào vài ví dụ có các ứng dụng SQL-CLR thực sự hữu ích; tìm kiếm trên Google và bạn sẽ nhận được 10 triệu kết quả, mỗi kết quả duy nhất trong số đó cho một số chuỗi liên kết ngớ ngẩn hoặc regex. Những điều này rất hữu ích, nhưng hãy dành vài phút để tìm hiểu về các URI SQL và UDA nói riêng và bạn sẽ bắt đầu thấy rất nhiều cách sử dụng cho chúng trong các ứng dụng của riêng bạn. Dĩ nhiên, đừng đi hạt - hãy suy nghĩ cẩn thận về việc có hay không có một giải pháp tốt hơn trong SQL thuần túy - nhưng cũng không giảm giá chúng.

+2

Đây là một trong những bài viết thông tin nhất mà tôi từng đọc. Cảm ơn bạn. –

+0

+1 rất độc đáo đặt –

5

Thao tác chuỗi - tìm kiếm biểu thức chính quy là kiểu cổ điển. Rất dễ phơi bày trong CLR, rất khó thực hiện trong T-SQL thẳng.

Xem this link để biết chi tiết về triển khai và điểm chuẩn nhỏ (SQLCLR is only 47 milliseconds compared to 6.187 seconds for the T-SQL UDF).

5

Thao tác chuỗi (regexes) đã được đề cập, nhưng cũng có số học DateTime, và tất nhiên là một dịch vụ web bên ngoài gọi là biggie khác.

+0

Xin chào Marc, bạn có thể đưa ra ví dụ về sự cố bạn sẽ giải quyết bằng cách truy cập vào các dịch vụ web bên ngoài trong proc CLR không? +1 cho tính hữu dụng cho chắc chắn. –

+0

Rất nhiều thứ - ví dụ: nhận được tỷ giá hối đoái cập nhật, cập nhật thông tin chứng khoán và nhiều hơn nữa –

2
  • Tuỳ chỉnh tập hợp
  • Chuỗi thao tác
  • loại Tuỳ chỉnh dữ liệu

Thành thật mà nói, tôi chỉ thấy xử lý chuỗi trong đó bao gồm CSV tách thành hàng.

Tôi muốn xem xét bất kỳ điều gì cần nhiều hơn thì mức độ tin cậy mặc định nằm ngoài giới hạn, trừ khi tôi là một DBA làm công cụ loại DBA.

Từ MSDN với RegEx và RSS feed ví dụ: Using CLR Integration in SQL Server 2005

3

Dưới đây là một ví dụ về một cái gì đó tôi đã sử dụng procs CLR cho rằng tôi nghĩ là gọn gàng:

Timed cập nhật dữ liệu từ bên ngoài webservices sử dụng CLR được lưu trữ procs và các công việc SQL.

Chúng tôi có một ứng dụng đồng bộ hóa một số dữ liệu mà nó theo dõi với nguồn cấp dữ liệu ngành bên ngoài. Đồng bộ hóa chạy hàng tuần cho mọi thứ và theo yêu cầu cho các bản cập nhật đơn lẻ nên tôi đã có API webservice hiện có để truy cập nó. Mọi thứ đã được lên lịch bởi một dịch vụ cửa sổ nhưng tôi nghĩ tại sao không thể lên lịch cho họ như các công việc SQL khác của chúng ta ??

Tôi đã tạo thủ tục được lưu trữ CLR để điều chỉnh API webservice của ứng dụng. Sau đó, tôi đã thêm một vài parm cho @RecordID để hỗ trợ đồng bộ hóa đơn và lập lịch biểu trong các công việc SQL của người quản lý doanh nghiệp.

Bây giờ tôi có thể sử dụng công việc để chạy đồng bộ hóa dB hoặc sử dụng proc trong các chương trình SQL khác hoặc Trình kích hoạt để cập nhật dữ liệu từ nguồn cấp dữ liệu bên ngoài.

Có thể làm sạch API webservice ứng dụng trong tương lai và chỉ sử dụng trực tiếp dịch vụ web bên ngoài. Mặc dù vậy, điều này rất nhanh để thực hiện và một cách tuyệt vời để mở rộng chức năng cho nhóm SQL.

1

Rất hữu ích khi kéo dữ liệu ra khỏi hệ thống không cung cấp giao diện SQL truyền thống hoặc việc triển khai giao diện đó của nhà cung cấp là phụ cận.

Chúng tôi có một ứng dụng cốt lõi được xây dựng trên nền tảng MUMPS cũ, chạy trên cơ sở dữ liệu Bộ đệm ẩn Intersystems. Dữ liệu là phân cấp, không quan hệ trong tự nhiên. Mảng toàn cục chính (ví dụ: bảng) có nhiều cấp dữ liệu và các phần tử được nhóm lại với nhau theo số tài khoản. Quét thậm chí một cột yêu cầu toàn bộ toàn cầu được tải từ đĩa và phải mất hơn 8 giờ. Nhà cung cấp không cung cấp trình điều khiển ODBC và ánh xạ cho các hình cầu, nhưng nó thường dẫn đến việc quét và truy vấn cực kỳ chậm.

Tôi đã xây dựng một hàm có giá trị của bảng, sử dụng chương trình ObjectScript (phương ngữ của hệ thống MUMPS), thực thi nó trên máy chủ Cache và trả về các dòng đầu ra dưới dạng hàng dữ liệu. Tôi có thể thu nhỏ đường dẫn truy cập dữ liệu ở phía MUMPS (đó thực sự là những gì cần để truy cập dữ liệu hiệu quả) bằng cách cung cấp một chương trình cụ thể để thực thi ở phía đó và sau đó dễ dàng nhập dữ liệu vào MSSQL như một nguồn dữ liệu nội tuyến đặc biệt.

Tôi có thể sử dụng TVF để thúc đẩy lựa chọn dữ liệu hoặc sử dụng CROSS APPLY để thực hiện tra cứu ở đầu bên kia và nó có hiệu quả hợp lý. Tôi thậm chí có thể chạy nhiều truy vấn trên đầu cuối từ xa song song nếu tôi buộc MSSQL sử dụng một kế hoạch thực thi song song.

+0

> "và trả về các dòng đầu ra dưới dạng hàng dữ liệu". Bạn đã đặt dữ liệu vào một System.Data.DataTable đầu tiên? Tôi có một số chức năng trợ giúp để viết bảng dữ liệu nhưng tự hỏi làm thế nào nó có thể được thực hiện với một IEnumerable ví dụ. – tbone

+0

Có một phương thức FillRow với chức năng định nghĩa bảng truyền trực tuyến, có chức năng chiếu cố định các hàng. Trong phiên bản gốc, tôi đã trả về 8 trường ký tự từ truy vấn dưới dạng F1, F2, F3 ... –

+0

Cảm ơn - ví dụ liên quan mà tôi nghĩ: http://stackoverflow.com/questions/6901811/sql-clr-streaming- table-valued-function-results – tbone

Các vấn đề liên quan