2011-08-24 30 views
5

Đây là câu hỏi "hướng dẫn" hoặc "cách tiếp cận tốt nhất" kỹ thuật.C# LINQ và các tính toán liên quan đến các tập dữ liệu lớn

Chúng tôi có yêu cầu hiện tại để truy xuất hồ sơ từ cơ sở dữ liệu, đặt chúng vào danh sách 'trong bộ nhớ' và sau đó thực hiện một loạt các phép tính trên dữ liệu, tức là giá trị tối đa, trung bình và một số thống kê tùy chỉnh cụ thể hơn .

Đưa dữ liệu vào danh sách 'trong bộ nhớ' không phải là vấn đề khi chúng tôi sử dụng NHibernate làm ORM và nó thực hiện công việc tuyệt vời để truy xuất dữ liệu từ cơ sở dữ liệu. Lời khuyên tôi đang tìm kiếm là cách chúng tôi nên thực hiện tốt nhất các phép tính trên danh sách dữ liệu kết quả. Lý tưởng nhất là tôi muốn tạo ra một phương pháp cho mỗi thống kê, MaximumValue(), AverageValueUnder100(), MoreComplicatedStatistic() vv vv Tất nhiên chuyển các biến cần thiết cho mỗi phương pháp và có nó trả về kết quả. Cách tiếp cận này cũng sẽ làm cho việc kiểm tra đơn vị trở nên dễ dàng và cung cấp cho chúng tôi mức độ phù hợp tuyệt vời.

Sẽ có một lần truy cập hiệu suất nếu chúng tôi thực hiện truy vấn LINQ cho mỗi phép tính hoặc nên hợp nhất nhiều cuộc gọi đến từng phương pháp thống kê trong ít nhất LINQ truy vấn nhất có thể. Ví dụ, nó không có ý nghĩa nhiều khi chuyển danh sách dữ liệu sang một phương thức có tên là AverageValueBelow100 và sau đó chuyển toàn bộ danh sách dữ liệu sang phương thức khác AverageValueBelow50 khi chúng có hiệu quả có thể được thực hiện với một truy vấn LINQ.

Làm cách nào chúng tôi có thể đạt được mức độ chi tiết và tách biệt cao mà không bị mất hiệu suất?

Bất kỳ lời khuyên nào ... là câu hỏi đủ rõ ràng?

+4

Cách tiếp cận tốt nhất là thực hiện các truy vấn đối với cơ sở dữ liệu nơi bạn có lợi ích của các chỉ mục để cải thiện hiệu suất –

+0

thực sự? thay vì quá trình 'trong bộ nhớ' chúng ta sẽ tốt hơn để truy vấn cơ sở dữ liệu. một số tính toán khá phức tạp vì vậy tôi không hoàn toàn chắc chắn đây sẽ là cách tiếp cận tốt nhất. – Rowen

+1

Hầu hết các cơ sở dữ liệu thường nhanh hơn –

Trả lời

1

Tùy thuộc vào độ phức tạp của phép tính, tốt nhất là nên thực hiện điều đó trong cơ sở dữ liệu. Nếu nó là phức tạp đáng kể mà bạn cần phải mang nó vào như các đối tượng và mã hóa chi phí trên, bạn có thể muốn tránh nhiều lần lặp lại trên tập kết quả của bạn. bạn có thể muốn xem xét sử dụng Tổng hợp. Xem http://geekswithblogs.net/malisancube/archive/2009/12/09/demystifying-linq-aggregates.aspx để thảo luận nếu có. Bạn sẽ có thể kiểm tra từng đơn vị tổng hợp một cách riêng biệt, nhưng sau đó (có khả năng) dự án tổng hợp nhiều trong một lần lặp đơn lẻ.

1

Tôi không đồng ý rằng tốt nhất là "làm tất cả trong cơ sở dữ liệu".

Các bài viết LINQ được viết tốt sẽ dẫn đến các truy vấn SQL tốt được thực hiện đối với cơ sở dữ liệu, nên hiệu suất đủ tốt (nếu bạn không làm công cụ dwh). Đây là giả sử bạn đang sử dụng nhà cung cấp LINQ cho NHibernate và không phải LINQ to Objects.

Trông nó đẹp, bạn có thể thay đổi dễ dàng và giữ logic kinh doanh của bạn ở một nơi.

Nếu điều đó quá chậm đối với nhu cầu của bạn, bạn có thể kiểm tra mã SQL được tạo và tinh chỉnh truy vấn LINQ, hãy thử biên dịch trước chúng, và cuối cùng bạn vẫn có thể quay lại để viết các thủ tục được lưu trữ yêu dấu để truyền bá logic kinh doanh của bạn khắp nơi.

Sẽ có lần truy cập hiệu suất không? Yeah, bạn có thể mất một vài millisecs, nhưng đó là giá trị mà bạn phải trả tiền để tách logic của bạn?

+0

Tôi đã không đề xuất làm tất cả trong cơ sở dữ liệu. Tôi đã chỉ khuyên chống lại tất cả các dữ liệu trong bộ nhớ và sau đó thực hiện những gì có hiệu quả sẽ được LINQ để đối tượng truy vấn đối với điều đó. –

0

Để trả lời câu hỏi "Tôi muốn tạo phương pháp cho từng thống kê", tôi khuyên bạn nên xây dựng một loại lớp thống kê.Dưới đây là một số mã giả để diễn tả ý tưởng:

class Statistician 
{ 
    public bool MustCalculateFIRSTSTATISTIC { get; set; } // Please rename me! 
    public bool MustCalculateSECONDSTATISTIC { get; set; } // Please rename me! 

    public void ProcessObject(object Object) // Replace object and Rename 
    { 
     if (MustCalculateFIRSTSTATISTIC) 
      CalculateFIRSTSTATISTIC(Object); 

     if (MustCalculateFIRSTSTATISTIC) 
      CalculateSECONDSTATISTIC(Object); 
    } 

    public object GetFIRSTSTATISTIC() // Replace object, Rename 
    { /* ... */ } 
    public object GetSECONDSTATISTIC() // Replace object, Rename 
    { /* ... */ } 

    private void CalculateFIRSTSTATISTIC(object Object) // Replace object 
    { /* ... */ } 
    private void CalculateSECONDSTATISTIC(object Object) // Replace object 
    { /* ... */ } 
} 

Sẽ Tôi đã làm điều này, có lẽ tôi sẽ cố gắng để làm cho nó chung chung và sử dụng các bộ sưu tập của các đại biểu thay vì phương pháp này, nhưng kể từ khi tôi không biết hoàn cảnh của bạn , Tôi sẽ để nó cho điều đó. Cũng lưu ý rằng tôi chỉ sử dụng các thành viên Object của lớp đối tượng, nhưng đó là chỉ vì tôi không đề nghị bạn sử dụng DataRows, Entities, hoặc những gì không; Tôi sẽ để điều đó cho những người khác biết thêm về tôi về chủ đề này!

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