2010-05-14 91 views
27

Xét đoạn code dưới đây:DataView.RowFilter Vs DataTable.Select() vs DataTable.Rows.Find()

Dataview someView = new DataView(sometable) 
someView.RowFilter = someFilter; 

if(someView.count > 0) { …. } 

Khá một số điều mà nói Datatable.Select() là tốt hơn so với sử dụng DataViews, nhưng đây là trước khi VS2008.

Solved: The Mystery of DataView's Poor Performance with Large Recordsets
Array of DataRecord vs. DataView: A Dramatic Difference in Performance

Googling về chủ đề này tôi thấy một số bài viết/chủ đề diễn đàn mà đề cập đến Datatable.Select() chính nó là khá buggy (không chắc chắn về điều này) và hoạt động không tốt trong các tình huống khác nhau.

Trên chủ đề này (ms) Best Practices ADO.NET) đề xuất rằng nếu có khóa chính được xác định trên một phương thức tìm kiếm() hoặc find() có thể được sử dụng trong Datatable.Select().

Bài viết này here (.NET 1.1) tiêu chuẩn tất cả ba phương pháp tiếp cận cộng thêm một vài điều nữa. Nhưng điều này là dành cho phiên bản 1.1 vì vậy không chắc chắn nếu đây là hợp lệ vẫn còn ngay bây giờ. Accroding này DataRowCollection.Find() tốt hơn tất cả các phương pháp tiếp cận và Datatable.Select() tốt hơn DataView.RowFilter.

Vì vậy, tôi khá bối rối về những gì có thể là cách tiếp cận tốt nhất về việc tìm các hàng trong một dữ liệu. Hoặc không có cách nào tốt để làm điều này, nhiều giải pháp tồn tại tùy thuộc vào kịch bản?

+0

Cảm ơn bạn đã nhận phần thưởng! – thmshd

Trả lời

45

Bạn đang tìm kiếm "cách tiếp cận tốt nhất để tìm hàng trong một dữ liệu", vì vậy trước tiên tôi phải hỏi: "tốt nhất" cho cái gì? Tôi nghĩ, bất kỳ kỹ thuật nào cũng có kịch bản mà nó có thể phù hợp hơn với những người khác.

Trước tiên, hãy xem DataView.RowFilter: Một DataView có một số ưu điểm trong Ràng buộc dữ liệu. Nó rất có định hướng xem nên nó có tính năng phân loại, lọc hoặc tìm kiếm mạnh mẽ, nhưng tạo ra một số chi phí và không được tối ưu hóa cho hiệu suất. Tôi sẽ chọn DataView.RowFilter cho các bản ghi nhỏ hơn và/hoặc nơi bạn tận dụng các tính năng khác (như, một ràng buộc dữ liệu trực tiếp với chế độ xem).

Hầu hết các thông tin về DataView, mà bạn có thể đọc trong các bài đăng cũ hơn, vẫn áp dụng.

Thứ hai, bạn nên thích DataTable.Rows.Find qua DataTable.Select nếu bạn chỉ muốn một lần truy cập. Tại sao? DataTable.Rows.Find chỉ trả về một hàng duy nhất. Về cơ bản, khi bạn chỉ định khóa chính, một cây nhị phân được tạo ra. Điều này có một số chi phí liên quan đến nó, nhưng vô cùng tăng tốc độ truy xuất.

DataTable.Select là chậm hơn, nhưng có thể rất tiện dụng nếu bạn có nhiều tiêu chí và không quan tâm đến các hàng được lập chỉ mục hoặc không lập chỉ mục: Nó có thể tìm về cơ bản mọi thứ nhưng không được tối ưu hóa cho hiệu suất. Về cơ bản, DataTable.Select phải đi bộ toàn bộ bảng và so sánh mọi bản ghi với tiêu chí bạn đã nhập.

Tôi hy vọng bạn sẽ thấy tổng quan này hữu ích.

Tôi khuyên bạn nên xem this article, điều này hữu ích cho tôi về các câu hỏi về hiệu suất. Bài đăng này chứa một số trích dẫn từ nó.

Một chút UPDATE: Bằng cách này, điều này có vẻ hơi ngoài phạm vi câu hỏi của bạn, nhưng giải pháp gần như luôn là giải pháp nhanh nhất để lọc và tìm kiếm trên chương trình phụ trợ.Nếu bạn muốn đơn giản và có SQL Server làm chương trình phụ trợ và .NET3 + trên ứng dụng khách, hãy truy cập LINQ-to-SQL. Tìm kiếm các đối tượng LINQ rất thoải mái và tạo các truy vấn được thực hiện trên phía máy chủ. Trong khi LINQ-to-Objects cũng là một kỹ thuật rất thoải mái nhưng cũng chậm hơn. Trong trường hợp bạn không biết đã ....

+0

Tôi chỉ tìm thấy một trường hợp kết quả khác nhau giữa các kỹ thuật .Select và RowFilter. Trong trường hợp của tôi, chọn 532 hàng và RowFilter đã trở về 540. Tôi tìm thấy sự khác biệt có liên quan đến khoảng trống thừa trong dữ liệu bảng và giải quyết nó bằng cách sử dụng Trim trong câu lệnh chọn TRIM (VendorNumber) = '500' – James

20

bài Thomashaid của tiền nó lên độc đáo:

  • DataView.RowFilter là ràng buộc.
  • DataTable.Rows.Find là để tìm kiếm bằng khóa chính chỉ.
  • DataTable.Select là để tìm kiếm theo nhiều cột và cũng để chỉ định đơn đặt hàng.

Tránh tạo nhiều DataView trong vòng lặp và sử dụng RowFilters để tìm kiếm bản ghi. Điều này sẽ làm giảm đáng kể hiệu suất.

Tôi muốn thêm rằng DataTable.Select có thể tận dụng các chỉ mục. Bạn có thể tạo một chỉ mục trên một DataTable bằng cách tạo một DataView và xác định một thứ tự sắp xếp:

DataView dv = new DataView(dt); 
dv.Sort = "Col1, Col2"; 

Sau đó, khi bạn gọi DataTable.Select(), nó có thể sử dụng chỉ số này khi chạy truy vấn. Chúng tôi đã sử dụng kỹ thuật này để cải thiện nghiêm túc hiệu suất ở những nơi mà chúng tôi sử dụng cùng một truy vấn nhiều lần. (Lưu ý rằng đây là trước khi LINQ tồn tại.)

Bí quyết là xác định thứ tự sắp xếp chính xác cho câu lệnh Select. Vì vậy, nếu truy vấn của bạn là "Col1 = 1 và Col2 = 4", thì bạn sẽ muốn "Col1, Col2" như trong ví dụ ở trên.

Lưu ý rằng việc tạo chỉ mục có thể phụ thuộc vào các cuộc gọi thực tế để tạo DataView. Chúng tôi đã phải sử dụng các nhà xây dựng new DataView(DataTable dt), và sau đó chỉ định các Thuộc tính sắp xếp trong một bước riêng biệt. Hành vi có thể thay đổi đôi chút với các phiên bản .NET khác nhau.

+1

Đây là siêu tiện dụng. Tôi không thể tin rằng đây không phải là tài liệu trên MSDN. Với 1 dòng mã, tôi đã cải thiện đáng kể hiệu suất của các cuộc gọi DataTable.Select() mà không làm tất cả các công việc FindRows() và từ điển ngớ ngẩn xung quanh. THANKS –

+1

siêu, điều đó làm cho ngày của tôi. Bây giờ các truy vấn nhanh hơn 300%! – JohanLarsson

+1

Nếu bạn duyệt qua nguồn .Net cơ bản, bạn sẽ thấy thường xuyên. Chọn() sẽ tự tạo một chỉ mục, nếu các điều kiện là đúng. Chẳng hạn như khi một biểu thức đơn giản như "col1 = 3 và col2 = 4" được sử dụng. Bạn có thể thấy điều này bằng cách kiểm tra trường [indexes] riêng của bảng sau khi chọn. Trong những trường hợp đó, không cần tạo một DataView. Câu trả lời ở trên cũng không hiệu quả đối với tôi, tôi cần tạo một DataView chỉ với hàm tạo bảng và sau đó đặt riêng thuộc tính [Sort]. Không chắc chắn lý do tại sao ... – LMK