Bạn có nên từ bỏ khung ORM khi bạn cần triển khai thao tác hàng loạt không?


15

Đây là một tình huống phổ biến:

  • Bạn cần triển khai một hoạt động hàng loạt trong một ứng dụng sử dụng khung ORM.
  • Sau lần vượt qua đầu tiên, bạn đã nhận thấy các vấn đề hiệu suất đáng kể.

Đây là câu hỏi của tôi:

  • Trong tình huống này, bạn có nên ưu tiên một giải pháp bao gồm SQL thô không?
  • Hoặc có những mẫu thiết kế nổi tiếng nào có thể giúp bạn giảm thiểu các vấn đề thường liên quan đến hoạt động hàng loạt với khung ORM không?

BIÊN TẬP:

  • Tôi không hỏi liệu bạn có nên xóa khung ORM khỏi toàn bộ ứng dụng không.
  • Tôi đang hỏi: Bạn có nên từ bỏ khung ORM cho phần nhỏ của ứng dụng này không?

Tôi không biết nếu bạn cần làm gì cả, nhưng bạn đã thử Trạm trộn hoạt động với số lượng lớn của bạn?
ChrisAnnODell

Câu trả lời:


13

Các ORM không có ý định chiếm quyền truy cập hoàn toàn vào cơ sở dữ liệu của bạn. Sử dụng chúng cho 80% mã đó là CRUD, thứ quá tẻ nhạt để tự viết. Sử dụng các thủ tục được lưu trữ, SQL động hoặc bất cứ điều gì bạn muốn cho 20% còn lại cần được tối ưu hóa cẩn thận.


4
Điều đó sẽ hoạt động nếu sự trừu tượng hóa cơ sở dữ liệu không phải là một trong những lý do chính khiến bạn quyết định sử dụng ORM.

@ Pierre303, tôi đang gặp khó khăn trong việc hiểu nhận xét của bạn. Ý anh là gì?
Đánh dấu Canlas

@MarkCanlas: Tôi nghĩ rằng anh ấy có nghĩa là "trừu tượng hóa cơ sở dữ liệu", theo nghĩa là bạn có thể thay đổi cơ sở dữ liệu (ví dụ: đi từ SQL Server sang MySQL) nếu bạn muốn làm như vậy. Trong thực tế, trường hợp sử dụng này hầu như không bao giờ xảy ra.
Robert Harvey

1
Bạn vẫn có thể tạo ra sự trừu tượng. Hầu hết các ORM thực sự hỗ trợ nhiều nhà cung cấp / phương ngữ đều hỗ trợ mã dành riêng cho nhà cung cấp / phương ngữ. Bạn có thể triển khai các hoạt động như liên kết chèn / mảng số lượng lớn / TVP / bất cứ điều gì cho các cơ sở dữ liệu cụ thể và để nó quay lại chậm dần cho các nhà cung cấp không được hỗ trợ như SQLite. Tệ nhất là bạn có thể chia chức năng có thể là hàng loạt thành một giao diện / lớp riêng và phụ trong một triển khai khác dựa trên các tham số xây dựng hoặc cấu hình.
Aaronaught

Có phương ngữ tùy chỉnh có thể giúp đỡ, cũng như mã cụ thể cho các vấn đề cụ thể. Tuy nhiên, để điều này khả thi trên quan điểm tài chính, điều này phải được giới hạn ở mức tối thiểu nghiêm ngặt. Các chức năng tùy chỉnh theo yêu cầu của chúng tôi (phương ngữ) chiếm chưa đến 0,1% tổng số cơ sở mã truy cập dữ liệu. Tôi sẽ thực sự quan tâm nếu nó còn hơn thế nữa.

7

Tôi sử dụng ORM (nHibernate) trong một ứng dụng đòi hỏi hiệu năng cao và xử lý hàng tỷ hồ sơ. Theo thời gian, chúng tôi nhận thấy rằng hầu hết các vấn đề hiệu suất quan trọng đều liên quan đến cách sử dụng ORM của chúng tôi thay vì chỉ do ORM.

ORM không nên thay thế kiến ​​thức cơ sở dữ liệu bắt buộc của bạn. Đó là một công cụ bạn sử dụng để có được năng suất và tính linh hoạt hơn trong mã của mình, nhưng bạn sẽ cần biết các quy trình cơ bản để tối ưu hóa hiệu suất của mình.

Bạn đã không chỉ định một ORM cụ thể, vì vậy đây là những điều chúng tôi đã làm để cải thiện hiệu suất:

  • Chúng tôi đã sử dụng một hồ sơ ORM. (chúng tôi đã sử dụng nhprof)
  • Chúng tôi đã sử dụng một hồ sơ cơ sở dữ liệu. (chúng tôi đã sử dụng SQL Server Profiler)
  • Chúng tôi đọc càng nhiều bài viết càng tốt về chủ đề này. (Nhiều phần có sẵn cho nHibernate ngoài toàn bộ chương về chủ đề này trong tài liệu)
  • Chúng tôi đã mua những cuốn sách cụ thể về hiệu suất và khả năng mở rộng.
  • Chúng tôi tạo ra hệ thống điểm chuẩn để kiểm tra sự tối ưu của chính chúng tôi.
  • và quan trọng hơn, chúng tôi đã có thể kiểm tra mã của chúng tôi với các khách hàng thực tế với dữ liệu khổng lồ. Điều đó một mình đã giúp chúng tôi phát hiện ra hầu hết các vấn đề trong ứng dụng của chúng tôi.

1

Chúng tôi đã quản lý để làm điều đó với Entity Framework, nhưng ứng dụng của chúng tôi đã thực hiện rất nhiều thao tác theo kiểu hàng loạt (chúng tôi sẽ viết một số lượng lớn các bản ghi vào các bảng riêng lẻ), vì vậy nó rất phù hợp. Tôi chắc chắn sẽ xem liệu có thể giữ lại khung ORM nếu có thể hay không, chỉ để giảm số lượng mã mục đích đặc biệt trong ứng dụng của bạn. Có thể đệm ghi, sau đó thực hiện chúng như một nhóm? Bạn mất ngữ nghĩa giao dịch, nhưng nếu bạn đang thực hiện các hoạt động hàng loạt, tôi cho rằng bạn đã đồng ý với điều đó.


1

ORM không làm gì kỳ diệu. Họ dịch các phương thức truy cập đối tượng sang SQL. Các câu lệnh SQL họ thực thi không nhất thiết phải chậm hơn SQL mà bạn viết bằng tay. Như đã nói, có một vài vấn đề mà bạn có thể vấp phải:

  1. Giao dịch: Một hoạt động hàng loạt lớn hầu như luôn luôn nhanh hơn nhiều giao dịch nhỏ cùng thực hiện cùng một điều. Do đó, nếu các cuộc gọi phương thức ORM của bạn sử dụng các giao dịch chi tiết (ví dụ, các phương thức kiểu bản ghi hoạt động trong các thực thể Spring Roo được chú thích là @Transactional theo mặc định), các hoạt động hàng loạt sẽ bị chậm. Nếu đó là trường hợp trong ứng dụng của bạn, bạn nên xem xét logic giao dịch của mình.
  2. Bộ nhớ đệm: Trong Hibernate, bộ đệm cấp một cho phép người quản lý thực thể của bạn tránh các chuyến đi khứ hồi không cần thiết đến cơ sở dữ liệu. Điều tốt nói chung, nhưng xấu cho chèn số lượng lớn, dẫn đến việc tắc nghẽn bộ đệm không cần thiết, dẫn đến giảm hiệu suất ứng dụng. Nếu đó là vấn đề của bạn, bạn nên xem mẫu Batching được đề xuất ở trên bởi ChrisAnnODell. Chúng tôi sử dụng nó trong các nhà nhập khẩu của chúng tôi và nó tăng tốc độ chèn rất nhiều.

Không có gì sai khi sử dụng SQL gốc để cải thiện hiệu suất. Nhưng trước tiên hãy chắc chắn rằng bạn hiểu những gì đang làm bạn chậm lại.


Để tránh bộ đệm, hãy sử dụng StatlessSession. Ngoài ra, tránh ID tăng tự động. HiLo hoặc Guid nên được sử dụng thay thế.

1

Bỏ qua ORM. Không chỉ vậy mà bỏ qua sql "thường xuyên" là tốt. Sử dụng một tiện ích hàng loạt của cơ sở dữ liệu của bạn để chèn các tập dữ liệu cực lớn vào bảng phân tầng. Sau đó sử dụng sql để thực hiện các hoạt động dàn dựng của bạn.

ORM "hương vị của blog" của bạn có thể không hoạt động cho tất cả các tình huống.


Đúng vậy, những loại công cụ back-end này rất rắc rối để học, nhưng sau khoảng 3 hoặc 4 lần, bạn sẽ là một chuyên gia và có thể làm mọi việc nhanh hơn và đôi khi những điều không thể được thực hiện theo những cách khác. Nó giống như sự khác biệt giữa một cái xẻng và máy ủi. Tôi đã viết các công cụ kiểm soát tập lệnh cho các nền tảng khác nhau để đọc các tệp nhập văn bản và cập nhật dữ liệu với các hoạt động cấp thấp. Viết một công cụ như vậy cũng có thể làm cho cuộc sống của bạn dễ dàng hơn (hoặc ít nhất là thú vị hơn). Những thứ như thế này có thể được sử dụng để điều chỉnh dữ liệu tùy chỉnh khi cài đặt máy khách trong quá trình cập nhật phần mềm.

0

Đã ở trong tình huống đó. Đôi khi, bạn phải.

Một số ORM cho phép nhà phát triển bỏ qua mô hình đối tượng và đi thẳng đến lớp cơ sở dữ liệu.

Ngoài ra còn có ORM, sử dụng các hoạt động hàng loạt, được gói gọn, như Hướng đối tượng.


0

Như được đề cập bởi umlcat , có một số ORM sẽ cho phép bạn sử dụng các hoạt động hàng loạt.

Thậm chí tốt hơn, nhiều ORM có thể mở rộng, vì vậy bạn chỉ có thể viết phương thức của riêng mình để chạy các hoạt động hàng loạt, nếu chưa được hỗ trợ. Nếu thao tác hàng loạt trong ứng dụng của bạn là thứ bạn có thể tạo ra, tôi sẽ thêm nó dưới dạng một lớp trên ORM (để làm điều đó, có lẽ bạn sẽ cần phải viết SQL thô), nhưng sau đó trong ứng dụng, hãy sử dụng ORM phương pháp bạn đã thực hiện.

Điều này cũng làm cho thử nghiệm đơn vị và gỡ lỗi dễ dàng hơn. Khi bạn có phạm vi kiểm tra tốt cho các phương pháp ORM của mình, bạn có thể sử dụng nó trong các ứng dụng của mình. Mặt khác, gỡ lỗi SQL thô (đặc biệt là các SQL lớn có giao dịch và nhiều THAM GIA) có thể là một nỗi đau.

Có lần tôi mất gần một ngày để phát hiện ra lỗi trong một cuộc gọi SQL thô gần 100 LỘC và lỗi chỉ là một ký tự! Kể từ đó, tôi cố gắng tránh có SQL thô trong ứng dụng và có tất cả các quy trình SQL được kiểm tra đơn vị riêng biệt.


0

Vâng, không có bất kỳ thiết kế nào mà tôi biết. Tôi đoán là bạn đã đưa ra quyết định cho ORM vì một lý do, vì vậy việc từ bỏ ORM có thể không phải là điều bạn muốn. Tuy nhiên, trong những trường hợp này tôi nghĩ có chỗ để trộn cả hai giải pháp. Không có gì sai với điều đó, miễn là bạn làm điều đó một cách súc tích và ghi lại lý do tại sao bạn đi chệch khỏi việc sử dụng ORM mặc định trong phần mềm của bạn. Bên cạnh đó, một số khung ORM có một số phương tiện để thực hiện các hoạt động hàng loạt. Tôi biết nHibernate (ORM cho .NET framework) đã kết nối với StatlessSimes, vốn có ít chi phí hoạt động hơn, nhưng điều này vẫn có thể không mang lại cho bạn sự tăng cường hiệu quả mà bạn đang tìm kiếm. Trong trường hợp đó, chỉ cần sử dụng SQL thô.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.