2010-02-01 28 views
5

Tôi đang sử dụng NHibernate cho ORM và đã hợp nhất tải nhiều thực thể vào một truy vấn lớn.Độ trễ NHibernate rất cao

Tôi đang thực sự tải từ điển từ, khoảng 500 nghìn mục nhập và mỗi từ liên quan đến những từ khác. Chạy quá trình tải trong nền có thể rất phức tạp trong ứng dụng của chúng tôi, vì chúng tôi sẽ phải tải thủ công một mục nhập chưa được tải đúng thời gian, vì bất kỳ từ nào cũng có thể được yêu cầu bất cứ lúc nào. Yêu cầu duy nhất của chúng tôi là tất cả dữ liệu được tải nhanh nhất có thể. Tôi cũng đã thử sử dụng phiên không quốc tịch, nhưng có ngoại lệ là phiên không quốc tịch không thể tìm nạp bộ sưu tập (vì lý do nào đó, có thể nó không liên quan đến thực tế không có bộ nhớ cache cho phiên không trạng thái?)

Vấn đề là mặc dù truy vấn mất không quá 25 giây trong SQLServer, nó mất hơn 3 phút cho ICriteria.List().

Tôi đã sử dụng NHProf để lập hồ sơ quá trình tải và thấy rằng việc tạo ra các thực thể là một việc tốn kém, chiếm phần lớn thời gian tải trong NHibernate.

Tôi có thể làm gì để giảm độ trễ này không? Việc phân bổ bộ nhớ có tốn kém hay là "điền" dữ liệu?

Cảm ơn!

Trả lời

0

Lập cấu hình quy trình tạo (ví dụ với bộ phân tích hiệu suất VS) nên cho bạn biết chính xác hoạt động tốn kém là gì. Nếu bạn đã chơi với điều chỉnh tải lười biếng thì tôi nghĩ giải pháp duy nhất tốt là gói gọn danh sách trả về để cho phép phân trang trả về các khối nhỏ hơn trong một vài lần lặp. Tôi không chắc liệu NHibernate hỗ trợ danh sách kết quả lười biếng như JPA không (tức là không tải các thực thể từ trình đọc dữ liệu cho đến khi cần thiết).

4

Có lẽ bạn nên xem xét thực tế là NHibernate (giống như hầu hết ORM) không đặc biệt phù hợp (hoặc dự định) cho các loại tình huống tải hàng loạt. Có bao nhiêu hàng bạn đang cố tải, cho hay lấy? Bạn đang cố làm gì vậy? Pre-populate một bộ nhớ cache? Xử lý giống như hàng loạt?

Cảm giác ruột của tôi là bạn nên cân nhắc nghiêm túc mục đích của ứng dụng và chọn các công nghệ cơ bản phù hợp. Có lẽ bạn có thể làm sáng tỏ một số ý định/yêu cầu của bạn?

EDIT OK, từ nhận xét của bạn Tôi hiểu bạn đang cố gắng làm gì ở đây. Điều đầu tiên tôi muốn làm là tạo một nguyên mẫu đơn giản bằng cách sử dụng ADO.NET thô để tải cùng một dữ liệu, để có được cảm giác về hiệu suất tốt nhất có thể đạt được bằng cách sử dụng truy cập dữ liệu chuẩn và bộ nhớ trong bộ nhớ. Tiếp theo, fiddle xung quanh với các loại bộ sưu tập khác nhau để xem những gì thực hiện tốt khi populating và tìm kiếm. Nếu tải dữ liệu như thế này vẫn còn quá chậm, đã đến lúc bắt đầu xem xét các phương pháp tải dữ liệu khác: dựa trên tệp từ tệp dữ liệu cục bộ, hydrating các đối tượng được tuần tự hóa trước, một số dạng tải nhanh theo yêu cầu, v.v.

+0

Cảm ơn bạn đã trả lời nhanh! Tôi đang cố gắng tải hơn 500 nghìn hàng, mỗi hàng trong số đó là một thực thể. Mỗi thực thể có thể trỏ tới các thực thể khác. Tôi đang cố gắng đưa danh sách này càng nhanh càng tốt với tất cả các mối quan hệ liên hệ này. Tôi không viết bất cứ điều gì cho DB, nhưng sau khi thử nghiệm với tải chậm, tôi thấy nó không phù hợp với nhu cầu của tôi. Điều tốt nhất tiếp theo tôi có thể nghĩ là bằng cách nào đó đang tải dữ liệu trong một chủ đề khác trong một số kiểu mẫu của người tiêu dùng sản xuất, nhưng tôi không biết bạn làm thế nào. Bất kỳ ý tưởng? Bạn có bất kỳ mẹo nào cho các công nghệ khác không? Cảm ơn! –

+1

Tôi vẫn không có đầu mối về lý do tại sao bạn muốn tải nhiều thực thể liên quan đến nhau. Điều đó gây khó khăn cho việc đưa ra các đề xuất. Tải dữ liệu trong nền có thể có ý nghĩa, nhưng chỉ khi ứng dụng của bạn có thể bắt đầu làm bất cứ điều gì cần làm mà không có tất cả dữ liệu tại chỗ. Nói tóm lại, hãy cho chúng tôi biết bạn muốn đạt được điều gì, yêu cầu của bạn là gì, có thể chúng tôi có thể đưa ra cho bạn một đề xuất hoặc hai đề xuất phù hợp. – tijmenvdk

+0

Tôi đang thực sự tải một từ điển từ, khi mỗi từ liên quan đến những từ khác. Điều nền có thể rất phức tạp trong ứng dụng của chúng tôi, vì chúng tôi sẽ phải tải thủ công một mục nhập chưa được tải trước đó. Vấn đề là bất kỳ một trong những từ đó có thể được yêu cầu bất cứ lúc nào. Yêu cầu duy nhất của chúng tôi là tất cả dữ liệu được tải nhanh nhất có thể. Tôi cũng đã thử sử dụng phiên không quốc tịch, nhưng có ngoại lệ là phiên không trạng thái không thể tìm nạp bộ sưu tập ... –

3

Tải các thực thể 500k vào phiên NHibernate không phải là một ý tưởng hay. Phiên làm việc được thực hiện ngắn ngủi và giữ một số lượng thực thể tương đối nhỏ.

Nếu bạn muốn thực hiện loại xử lý theo lô này trong NHibernate, bạn nên xem StatelessSession thay vì phiên thông thường. Sử dụng phiên không trạng thái sẽ có khả năng cải thiện đáng kể hiệu suất trong trường hợp này. Tuy nhiên, khi sử dụng phiên không trạng thái, bạn sẽ mất đi những lợi ích của bộ nhớ cache cấp cao nhất NHibernate, chẳng hạn như theo dõi thay đổi.

Thông tin thêm về StatelessSession có thể được tìm thấy trong this articlein the NH docs tại nhibernate.info.

Trong trường hợp này, tôi cũng khuyên bạn nên xem xét sử dụng ADO.NET thẳng thay vì NHibernate. Tôi không nói rằng bạn nên chuyển đổi bạn toàn bộ chiến lược truy cập dữ liệu sang ADO.NET nhưng bạn có thể muốn xem xét sử dụng ADO.NET cho các hoạt động hàng loạt và sử dụng NHibernate cho các trường hợp khác.

+0

Cảm ơn. Tôi đã thử sử dụng phiên không quốc tịch, nhưng tôi gặp lỗi sau: SessionException: "không thể tìm nạp bộ sưu tập theo phiên không trạng thái". Tại sao điều này đúng? Có cách nào để phá vỡ điều này không? –

+1

Nếu bạn thực sự cần tải các thực thể với các bộ sưu tập con của chúng, thì StatelessSession cũng không phù hợp, vì nó bỏ qua các bộ sưu tập (theo các tài liệu tại NHForge). Lý do cho điều đó có lẽ là StatelessSession được thực hiện ở một mức độ gần gũi hơn với ADO.NET so với phiên bình thường. Có vẻ như ADO.NET sẽ là một lựa chọn tốt hơn NHibernate trong kịch bản của bạn. –

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