2009-10-06 60 views
5

Tôi đang làm việc với hệ thống lưu trữ dữ liệu trong một cấu trúc giống như bảng tính - ngày/giờ trong tiêu đề cột, số đo (ví dụ: tên bác sĩ, Rh, nhóm máu) trong cột đầu tiên của mỗi hàng và một giá trị trong ô giao nhau. Các báo cáo dựa trên cấu trúc này thường yêu cầu phải hiển thị 10 hoặc nhiều hơn các biện pháp này.Máy chủ SQL: Giá trị bảng nội tuyến UDF so với dạng xem nội tuyến

Vì mục đích báo cáo, tập dữ liệu cần phải có một hàng cho từng bệnh nhân, ngày/giờ đo được thực hiện và cột cho mỗi phép đo. Về bản chất, người ta cần xoay vòng cấu trúc 90 độ.

Tại một thời điểm, tôi thực sự đã sử dụng chức năng PIVOT của SQL Server để thực hiện điều đó. Vì nhiều lý do, nó trở nên rõ ràng rằng cách tiếp cận này sẽ không hoạt động. Tôi quyết định rằng tôi sẽ sử dụng chế độ xem nội tuyến (IV) để xoa bóp dữ liệu sang định dạng mong muốn. Truy vấn đơn giản tương tự như:

SELECT patient_id, 
     datetime, 
     m1.value AS physician_name, 
     m2.value AS blood_type, 
     m3.value AS rh 
    FROM patient_table 
INNER JOIN (complex query here 
       WHERE measure_id=1) m1... 
INNER JOIN (complex query here 
       WHERE measure_id=2) m2... 
LEFT OUTER JOIN (complex query here 
       WHERE measure_id=3) m3... 

Như bạn có thể thấy, trong một số trường hợp, những IV được sử dụng để hạn chế các bộ dữ liệu kết quả (INNER JOIN), trong trường hợp khác họ không hạn chế dataset (LEFT OUTER JOIN). Tuy nhiên, phần 'truy vấn phức tạp' về bản chất là giống nhau đối với từng biện pháp này, ngoại trừ sự khác biệt trong measure_id. Trong khi cách tiếp cận này hoạt động, nó dẫn đến các câu lệnh SQL khá lớn, giới hạn sử dụng lại và cho thấy truy vấn lỗi.

Suy nghĩ của tôi là thay thế cụm từ 'truy vấn phức tạp' và mệnh đề WHERE bằng một bảng giá trị UDF nội tuyến. Điều này sẽ đơn giản hóa các truy vấn một chút, giảm lỗi và tăng tái sử dụng mã. Câu hỏi duy nhất trong đầu tôi là biểu diễn. Cách tiếp cận UDF có dẫn đến giảm đáng kể hiệu suất không? Nó có thể cải thiện vấn đề?

Cảm ơn bạn đã dành thời gian và cân nhắc.

Trả lời

1

Bạn cũng có tùy chọn thứ ba; một VIEW truyền thống (giả sử rằng bạn có một chìa khóa để tham gia). Về lý thuyết, không nên có sự khác biệt về hiệu năng giữa ba tùy chọn vì SQL Server nên đánh giá và tối ưu hóa các kế hoạch tương ứng. Thực tế là đôi khi điều đó không xảy ra cũng như chúng tôi muốn.

Lợi ích của chế độ xem truyền thống là bạn có thể biến nó thành chế độ xem được lập chỉ mục và cung cấp cho SQL Server một trợ giúp hiệu suất khác; tuy nhiên, bạn sẽ phải kiểm tra và xem.

+0

Chế độ xem truyền thống sẽ không hoạt động ở khách hàng này vì DBA có khả năng kháng quá các đối tượng không được nhà cung cấp xác định trong DB. Kết quả là, hầu hết các truy vấn được nhúng trong mỗi báo cáo (chúng tôi đang sử dụng CR). Lý do tôi nghĩ về UDF là mô đun của họ. Phần khó khăn là bán DBA theo ý tưởng ... Chế độ xem được lập chỉ mục có tương tự như chế độ xem vật chất của Oracle không? – craig

+0

Tôi đã không làm việc với Oracle trong một thời gian dài, vì vậy tôi không biết. Tuy nhiên, tôi sẽ chỉ ra rằng một UDF là một đối tượng không được nhà cung cấp xác định, vì vậy bạn có thể chạy vào cùng một pushback ở đó. Tôi tin rằng câu trả lời của người phát biểu với một bảng tạm thời hoặc biến có thể là đặt cược tốt nhất của bạn nếu bạn bị giới hạn để sửa đổi các đối tượng. Cũng giống như một sang một bên, tôi có xu hướng tạo ra một db phụ với các bảng liên kết ngang, vv, khi giao dịch với các nhà cung cấp dbs. Bằng cách này tôi có thể có mã tùy chỉnh bên ngoài cơ sở dữ liệu của họ; bạn có thể muốn khám phá điều đó như một tùy chọn trong tương lai. –

+2

Chế độ xem được lập chỉ mục giống như chế độ xem vật chất của Oracles. Chế độ xem phải tuân theo các hạn chế nhất định: http://msdn.microsoft.com/en-us/library/ms191432.aspx và chỉ Enterprise Edition mới xem xét sử dụng chế độ xem được lập chỉ mục để truy cập dữ liệu. Phiên bản tiêu chuẩn và phiên bản thấp hơn buộc phải sử dụng chế độ xem iindexed một cách rõ ràng bằng cách thêm gợi ý NOEXPAND, xem http://msdn.microsoft.com/en-us/library/ms181151.aspx –

1

Câu trả lời Sql Server 2005: Bạn có thể giảm chế độ xem nội tuyến bằng cách sử dụng bảng tạm thời/var. Các vấn đề về Performace trên đây là các chèn tạm thời mà bạn yêu cầu cho mỗi lần truy cập trên truy vấn, nhưng nếu các tập kết quả đủ nhỏ, chúng có thể trợ giúp. bạn có thể sử dụng các khóa chính trên các bảng var và các khóa/chỉ mục chính trên các bảng tạm thời. Khác với belive bình thường, tôi đã tìm thấy một vài bài báo chỉ ra rằng cả hai temp/var bảng được lưu trữ trong db tạm thời.

Chức năng UDF, chúng tôi nhận thấy có ít hiệu suất hơn, khi bạn có nhiều lớp udfs trong các truy vấn phức tạp, nhưng sẽ duy trì khả năng sử dụng. Đảm bảo tạo chức năng chính xác cho các điều kiện khác nhau được chỉ định. Những người sẽ được sử dụng cho các kết nối bên trong, và những cái sẽ được sử dụng cho các phép nối trái.

Vì vậy, nói chung. Chúng tôi sử dụng UDF, nhưng khi chúng tôi thấy rằng hiệu suất làm suy giảm, chúng tôi di chuyển truy vấn để chèn các lựa chọn UDF vào các bảng temp/var và tham gia vào các bảng đó.

Tạo chức năng để dễ sử dụng/bảo trì và áp dụng hiệu suất nơi ở và khi được yêu cầu.

EDIT:

Nếu bạn được yêu cầu để chạy cho pha lê, và bạn có kế hoạch để sử dụng thủ tục lưu trữ, Có, bạn có thể thực hiện câu lệnh SQL bên trong SP để bảng temp/var.

Hãy cho tôi biết nếu bạn định sử dụng SP. Sql sau đó sẽ cache các kế hoạch sp với các tham số đã cho như requied.

Cũng từ kinh nghiệm trước đó với tinh thể, những điều cần tránh, được nhóm trong Crystal có thể được thực hiện trong SP, số trang nếu không được yêu cầu. và các cuộc gọi chức năng, nếu điều này có thể được xử lý trên máy chủ.

+0

Tha thứ sự thiếu hiểu biết của tôi, nhưng tôi có thể sử dụng một bảng temp/var trong một câu lệnh SQL chuẩn không? Nó cần chạy từ bên trong một công cụ báo cáo (Crystal Reports). Tôi đoán giải pháp của bạn đòi hỏi một SP, phải không? Nếu không, bạn có thể mở rộng về cách tiếp cận này nhiều hơn một chút không? Chúng tôi đang sử dụng SQL Server 2005. – craig

+0

bảng vars có thể được thêm vào sql được thực hiện đối với DB. Bạn đang sử dụng sql từ ứng dụng, hoặc trong Crystal? –

+0

Từ bên trong đối tượng Lệnh của Crystal Reports - về cơ bản là một câu lệnh raw-SQL. Tôi đã nhận thấy rằng ổ đĩa cơ sở dữ liệu (tức là ODBC hoặc OLEDB) có ảnh hưởng đến chức năng của SQL. Ví dụ, tôi đã có vấn đề trong quá khứ bằng cách sử dụng câu lệnh WITH với OLEDB, nhưng không phải với ODBC. Điều này có thể ảnh hưởng đến khả năng sử dụng các kỹ thuật nâng cao hơn của tôi. – craig

8

TVF được xác định chính xác sẽ không giới thiệu bất kỳ sự cố nào. Bạn sẽ tìm thấy nhiều xác nhận quyền sở hữu trên các TVF cho nổ mìn cho các vấn đề về hiệu năng so với các khung nhìn và các biến và các biến tạm thời. Điều bình thường không được hiểu là TVF hoạt động khác với quan điểm. Một định nghĩa khung nhìn được đặt vào truy vấn gốc và sau đó trình tối ưu hóa sẽ sắp xếp lại cây truy vấn khi nó thấy phù hợp (trừ khi mệnh đề NOEXPAND được sử dụng trên các khung nhìn được lập chỉ mục). TVF có ngữ nghĩa khác nhau và đôi khi, đặc biệt khi cập nhật dữ liệu, kết quả đầu ra TVF này được đặt cho haloween protection. Nó giúp đánh dấu chức năng WITH SCHEMABINDING, xem Improving query plans with the SCHEMABINDING option on T-SQL UDFs.

Ngoài ra, điều quan trọng là phải hiểu khái niệm về hàm xác định và chính xác. Mặc dù chúng áp dụng chủ yếu cho funcitons giá trị vô hướng, TVF cũng có thể bị ảnh hưởng. Xem User-Defined Function Design Guidelines.

+0

Wow, khá một vài sắc thái tinh tế. Cảm ơn sự hiểu biết của bạn. – craig

+1

Tôi tin rằng một TVF, nếu nó là nội tuyến/không đa tầng, cũng được mở rộng bởi trình tối ưu hóa. Nói rằng Chế độ xem được mở rộng, nhưng không đề cập đến điều này cho TVF có vẻ hàm ý điều gì đó có thể gây hiểu lầm. Có thể cập nhật câu trả lời này để đề cập đến điều đó. Tôi không có chuyên gia về điều này mặc dù. – AaronLS

2

Vì bạn cần chuỗi SQL và có thể không có khả năng thêm chế độ xem hoặc UDF vào hệ thống, bạn có thể muốn sử dụng WITH ... AS để giới hạn truy vấn phức tạp đến một địa điểm (Ít nhất cho câu lệnh này .).

WITH complex(patientid, datetime, measure_id, value) AS 
(Select... Complex Query) 
SELECT patient_id 
,  datetime 
,  m1.value AS physician_name 
,  m2.value AS blood_type 
,  m3.value AS rh 
FROM patient_table 
INNER JOIN (Select ,,,, From complex WHERE measure_id=1) m1... 
INNER JOIN (Select ,,,, From complex WHERE measure_id=2) m2... 
LEFT OUTER JOIN (Select ,,,, From complex WHERE measure_id=3) m3... 
+0

Giả sử rằng 'truy vấn phức tạp' trả về 1.000.000 hàng không có mệnh đề WHERE (không, nhưng nó giúp minh họa cho câu hỏi của tôi). DB sẽ tạo ra 1.000.000 hàng một lần, lựa chọn từ nó cho mỗi tham gia (ba trong ví dụ của tôi). Hay nó làm một công việc tối ưu hóa tốt hơn điều này? Tôi không cho rằng tôi có thể thêm gợi ý INDEX vào nó? Tôi biết rằng các bảng bên dưới không được lập chỉ mục tốt và DB của chúng tôi sẽ không thêm bất kỳ chỉ báo không do nhà cung cấp nào xác định. – craig

+0

Biểu thức bảng chung (phức tạp) sẽ được tạo một lần và trong trường hợp này được gọi nhiều lần. Máy chủ SQL có thể sẽ tối ưu hóa việc gọi cho anh ta cùng một truy vấn nhiều lần, nhưng một truy vấn rất phức tạp có thể không. DBA của bạn sẽ cung cấp một số hỗ trợ trong việc kiểm tra truy vấn của bạn để thực hiện. – JeffO

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