OracleBulkCopy đặc biệt làm gì và làm cách nào để tối ưu hóa hiệu suất của nó?


14

Để tóm tắt các chi tiết cụ thể: Chúng tôi cần đưa khoảng 5 triệu hàng vào cơ sở dữ liệu của nhà cung cấp (Oracle). Mọi thứ đều tuyệt vời đối với các lô 500 nghìn hàng sử dụng OracleBulkCopy(ODP.NET), nhưng khi chúng tôi cố gắng tăng quy mô lên tới 5M, hiệu suất sẽ bắt đầu chậm khi thu thập thông tin khi chạm mốc 1M, chậm dần khi nhiều hàng được tải và cuối cùng Thời gian ra sau 3 giờ hoặc lâu hơn.

Tôi nghi ngờ nó có liên quan đến khóa chính trên bàn, nhưng tôi đã truy tìm các diễn đàn của Oracle và Stack Overflow để lấy thông tin và rất nhiều điều tôi đang đọc mâu thuẫn với điều đó (cũng, rất nhiều bài viết dường như mâu thuẫn với nhau ) . Tôi hy vọng rằng ai đó có thể thiết lập hồ sơ thẳng vào một số câu hỏi liên quan chặt chẽ về quy trình:

  1. OracleBulkCopylớp sử dụng tải thông thường hoặc đường dẫn trực tiếp? Có cách nào để tôi có thể xác nhận điều này, bằng cách này hay cách khác?

  2. Giả sử nó không sử dụng trực tiếp con đường tải: Có đúng là Oracle tự động cài đặt tất cả các chỉ số để sử dụng được trong thời gian tải và đặt chúng trở lại trực tuyến sau đó? Tôi đã đọc một số tuyên bố về hiệu ứng này nhưng một lần nữa, không thể xác nhận nó.

  3. Nếu số 2 là đúng, thì nó có nên tạo ra bất kỳ sự khác biệt nào về các chỉ mục trên bảng trước khi tôi bắt đầu một hoạt động sao chép số lượng lớn không? Nếu vậy, tại sao?

  4. Liên quan đến # 3, nói chung, có sự khác biệt thực tế nào không, giữa tải hàng loạt với chỉ số không sử dụng được so với thực tế giảm chỉ số trước khi tải và tạo lại sau đó?

  5. Nếu # 2 là không chính xác, hoặc nếu có một số hãy cẩn thận tôi không hiểu, sau đó nó sẽ làm cho bất kỳ sự khác biệt cho rõ ràng làm cho chỉ số không sử dụng được trước khi tải số lượng lớn, và sau đó một cách rõ ràng xây dựng lại nó sau đó?

  6. Có điều gì khác, ngoài việc xây dựng chỉ mục, có thể khiến hoạt động sao chép số lượng lớn tăng chậm dần khi ngày càng nhiều bản ghi được thêm vào không? (Có lẽ phải làm gì đó với việc đăng nhập, mặc dù tôi cho rằng các hoạt động hàng loạt không được ghi lại?)

  7. Nếu thực sự không có cách nào khác để tăng hiệu suất để loại bỏ việc bỏ PK / chỉ mục trước, tôi có thể thực hiện các bước nào để đảm bảo rằng chỉ mục không biến mất hoàn toàn, tức là nếu mất kết nối với cơ sở dữ liệu Giữa quá trình?


Lưu ý bên lề: Dữ liệu được sao chép đã được sắp xếp theo thứ tự theo PK, đây là chỉ mục duy nhất trên bảng.
Aaronaught

Bạn có đang sử dụng DataReader để đọc dữ liệu từ nguồn không?
bernd_k

@bernd_k: Không, tải hoàn toàn từ bộ nhớ. Đó chắc chắn không phải là nguồn đó là vấn đề.
Aaronaught

Câu trả lời:


13

Một vài ngày nữa để đọc và thử nghiệm và tôi đã có thể (hầu hết) trả lời rất nhiều trong số này:

  1. Tôi thấy điều này bị chôn vùi trong tài liệu ODP.NET (trớ trêu thay không có trong OracleBulkCopytài liệu):

    Tính năng Sao chép hàng loạt ODP.NET sử dụng cách tiếp cận tải đường dẫn trực tiếp, tương tự, nhưng không giống với Trình tải * SQL của Oracle. Sử dụng tải đường dẫn trực tiếp nhanh hơn tải thông thường (sử dụng SQL thông thườngINSERT ).

    Vì vậy, có vẻ như nó làm sử dụng đường dẫn trực tiếp.

  2. Điều này tôi đã có thể xác minh bằng cách thực hiện một thao tác sao chép số lượng lớn và nhận các thuộc tính chỉ mục từ SQL Developer. Các chỉ mục đã xuất hiện như UNUSABLEtrong khi bản sao hàng loạt đang được tiến hành. Tuy nhiên , tôi cũng phát hiện ra rằng OracleBulkCopy.WriteToServersẽ từ chối chạy nếu chỉ mục bắt đầu trong mộtUNUSABLE trạng thái, vì vậy rõ ràng sẽ có nhiều hơn ở đây, bởi vì nếu nó đơn giản như vô hiệu hóa và xây dựng lại chỉ mục thì nó không quan tâm đến trạng thái ban đầu.

  3. Nó làm cho một sự khác biệt cụ thể nếu chỉ số cũng là một hạn chế . Tìm thấy viên ngọc nhỏ này trong tài liệu được liên kết ở trên:

    Các ràng buộc được kích hoạt
    Trong một bản sao hàng loạt của Oracle, các ràng buộc sau được tự động bật theo mặc định:

    • NOT NULL
    • UNIQUE
    • PRIMARY KEY (các ràng buộc duy nhất trên các cột không null)

    NOT NULLcác ràng buộc được kiểm tra tại thời điểm xây dựng mảng cột. Bất kỳ hàng nào vi phạm các NOT NULLràng buộc đều bị từ chối.

    UNIQUEcác ràng buộc được xác minh khi các chỉ mục được xây dựng lại ở cuối tải. Chỉ mục được để ở trạng thái Chỉ mục không sử dụng được nếu vi phạm UNIQUEràng buộc.

    Tài liệu này hơi mơ hồ về những gì xảy ra trong quá trình tải, đặc biệt là với các khóa chính, nhưng có một điều hoàn toàn chắc chắn - nó hoạt động khác với khóa chính so với không có khóa . Vì ý OracleBulkCopychí vui vẻ cho phép bạn vi phạm các ràng buộc chỉ mục (và đưa chỉ số vào UNUSABLEtrạng thái khi hoàn thành), linh cảm của tôi là nó sẽ xây dựng chỉ mục PK trong bản sao hàng loạt nhưng đơn giản là không xác thực cho đến sau đó.

  4. Tôi không chắc liệu sự khác biệt quan sát được nằm trong chính Oracle hay chỉ là một sự châm biếm OracleBulkCopy. Ban giám khảo vẫn ra về điều này.

  5. OracleBulkCopysẽ đưa ra một ngoại lệ nếu một chỉ mục ban đầu ở UNUSABLEtrạng thái, vì vậy nó thực sự là một điểm cần thiết.

  6. Nếu có yếu tố khác, chỉ số (và chỉ số đặc biệt là PK) vẫn là quan trọng nhất, như tôi đã phát hiện ra bởi:

  7. Tạo một bảng tạm thời toàn cầu với cùng một lược đồ (sử dụng CREATE AS), sau đó sao chép số lượng lớn vào bảng tạm thời và cuối cùng thực hiện một bảng cũ đơn giản INSERTtừ bảng tạm thời vào bảng thực. Vì bảng tạm thời không có chỉ mục, bản sao hàng loạt xảy ra rất nhanh và cuối cùngINSERT cũng nhanh vì dữ liệu đã có trong một bảng (Tôi chưa thử gợi ý chắp thêm, vì bản sao bảng hàng 5M đã mất ít hơn 1 phút).

    Tôi vẫn chưa chắc chắn về sự phân nhánh tiềm năng của (ab) bằng cách sử dụng không gian bảng tạm thời theo cách này, nhưng cho đến nay nó vẫn không gây cho tôi bất kỳ rắc rối nào và nó an toàn hơn nhiều so với cách thay thế bằng cách ngăn chặn tham nhũng của các hàng hoặc chỉ mục.

    Thành công của điều này cũng cho thấy khá rõ rằng chỉ số PK là vấn đề, vì đó là sự khác biệt thực tế duy nhất giữa bảng tạm thời và bảng cố định - cả hai đều bắt đầu với các hàng 0 trong các bài kiểm tra hiệu suất.

Kết luận: Đừng bận tâm cố gắng sao chép hàng loạt hơn 100 nghìn hàng vào bảng Oracle được lập chỉ mục bằng ODP.NET. Hoặc bỏ chỉ mục (nếu bạn không thực sự cần nó) hoặc "tải trước" dữ liệu vào một bảng khác (không được lập chỉ mục).


Tôi không chắc chắn về việc kiểm tra các ràng buộc khóa chính. Tôi rất vui khi chèn hàng loạt dữ liệu tương tự vào bảng Oracle 2 lần và Chọn * hiển thị 2 hàng trùng lặp. Ở trạng thái đó, xóa là không thể, nhưng bảng cắt ngắn giúp quay trở lại trạng thái sạch.
bernd_k

@bernd_k: Deletekhông thể vì chỉ mục là UNUSABLE. Đó là kết quả của việc kiểm tra ràng buộc xảy ra ở cuối bản sao số lượng lớn.
Aaronaught

Tôi có một skript PowerShell đang chạy, gọi số lượng lớn vào cơ sở dữ liệu Oracle từ trình đọc dữ liệu SQL Server, tất cả các bảng mục tiêu có Khóa chính và tôi không gặp vấn đề gì với các bảng có tối đa 205278 hàng. Nhưng tôi rất cẩn thận trước tiên hãy điền đầy đủ các bảng chính trước khi điền vào các bảng chi tiết. Tôi đã không xóa bất kỳ chỉ mục nào khác trên bảng và tôi không gặp vấn đề gì khi các bảng ban đầu trống.
bernd_k

@bernd_k: Vâng, tôi cũng không gặp quá nhiều vấn đề ở tập đó (xem đoạn cuối của tôi). Đó là khi bạn đạt đến hàng triệu thứ mà nó trở nên khủng khiếp. Ngoài ra, có thể có một sự khác biệt nếu đôi khi bạn làm trống bảng sau mỗi bản sao số lượng lớn (bản này không bị xóa, nó sẽ được thêm vào và bạn biết làm thế nào các chỉ mục trở nên chậm hơn khi chúng lớn hơn).
Aaronaught

Có lẽ nó hữu ích khi bạn thực hiệnalter session set skip_unusable_indexes = true;
Wernfried Domscheit 6/11/2016

1

Dưới đây là một bài viết từ Oracle giải thích khi nào sẽ có lợi khi sử dụng chèn số lượng lớn hoặc khi nào không. Ngoài ra, có cái nhìn sâu sắc về những gì xảy ra ở cấp cơ sở dữ liệu.

http://docs.oracle.com/cd/B28359_01/server.111/b28319/ldr_modes.htmlm


3
Liên kết có xu hướng thối; bạn có thể muốn bao gồm thông tin liên quan từ liên kết trong câu trả lời của bạn.
mustaccio
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.