Oracle 11g: cải thiện hiệu suất của phần chèn


8

Tôi có một bảng gồm 500 triệu hàng (và đang phát triển)

Tôi đã làm như sau để cải thiện hiệu suất của chèn:

Về phía cơ sở dữ liệu:

  • bỏ tất cả các chỉ mục và các ràng buộc
  • đăng nhập bị vô hiệu hóa

Về phía ứng dụng:

  • đã chuyển từ các thực thể được quản lý JPA sang các truy vấn chèn gốc, thêm gợi ý APPEND Oracle vào truy vấn
  • đã cố gắng cam kết theo đợt trên 1k / 2k / 3k hàng
  • đã cố gắng viết song song (nhiều luồng, đếm luồng = đến lõi đếm trên máy chủ) vào một bảng

Điều này cho tôi khoảng 300 hàng mỗi giây

Ngoài ra đã thử:

  • viết song song theo lô vào nhiều bảng (để nhóm lại kết quả bằng UNION)

Điều này đã cho tôi khoảng 1k hàng mỗi giây, nhưng trên các bảng trống. Nhưng khi tôi điền vào các bảng với dữ liệu giả (200 triệu mỗi bảng), tốc độ chèn giảm xuống 250 - 300 mỗi giây.

Bất cứ ai có thể đề nghị tôi có thể làm gì khác để tăng tốc độ chèn? Về cơ bản tôi muốn hiểu thế nào là (cái có thể) là nút cổ chai trước tiên.

CẬP NHẬT: Bảng được phân vùng theo ngày chèn, bảng có khoảng 60 cột - hầu hết các cột là VARCHAR2 (2000 BYTE)


Bạn biết rằng với việc đăng nhập bị vô hiệu hóa, lỗi phương tiện giữa tải và hoàn thành bản sao lưu tiếp theo đầu tiên sẽ rời khỏi toàn bộ bảng hoặc các phần của nó trong trường hợp chèn đường dẫn trực tiếp, không thể phục hồi, phải không?
David Aldridge

1
(1) Chỉ một phiên có thể PHỤC HỒI bất cứ lúc nào trên bàn. (2) /*+APPEND*/gợi ý bị bỏ qua trên các chèn một hàng (nếu bạn INSERT INTO ... SELECTkhông bận tâm với phần bổ sung). (3) Bạn nên thiết lập một ví dụ SQL * Loader direct=trueđể thiết lập đường cơ sở theo đề xuất của @parsifal.
Vincent Malgrat

Bạn đang chạy trên phần cứng thực hay máy ảo? Nếu là VM, các tệp đĩa có thưa thớt không (tức là: không được phân bổ đầy đủ)? Ngoài ra, vui lòng chỉnh sửa câu hỏi của bạn với đầu ra từ báo cáo thống kê hoặc báo cáo awr (phần chờ hàng đầu).
Phil 26/03/13

Vấn đề / nhu cầu nào phân vùng bằng cách chèn ngày giải quyết / thỏa mãn?
Brian

Nguồn dữ liệu của bạn cho bảng này là gì? Đây có phải là tải hàng loạt từ tệp ASCII hay do người dùng tạo hoặc một cái gì đó khác. Hãy cụ thể.
RMAN Express

Câu trả lời:


5

Chỉ cần xem bản cập nhật, bảng 60 col với các trường chủ yếu là VARCHAR (2k) - nghĩa là (có khả năng) là một bảng quái vật.

Điều đầu tiên trước tiên ...

Bạn phải hiểu nút cổ chai của bạn ĐẦU TIÊN. Về phía ứng dụng, hãy quay trở lại giải pháp chèn hàng loạt một luồng (1/2 / 3k một lần) và bắt đầu chạy nó và đăng nhập vào máy DB và chạy 'top' - xem bao nhiêu thời gian quá trình DB đang mất VÀ bao nhiêu (nếu có) wa% thời gian máy đang hiển thị.

Nếu top hiển thị cho bạn BẤT K wa% thời gian, điều đó có nghĩa là DB của bạn bị ràng buộc I / O và bạn có thể cần phải xem xét nhiều máy DB (phân đoạn) hoặc xem xét việc ném SSD vào máy chủ.

Đó là nó; nghiên cứu của bạn dừng ở đây. Không quan trọng DB chiếm bao nhiêu CPU hay ứng dụng khách ứng dụng của bạn đã bão hòa như thế nào; nếu bạn đang gặp phải các vấn đề về độ trễ I / O trên máy chủ DB, thì nó sẽ nhanh như nó sẽ giúp bạn.

MIPO Nếu không có vấn đề về phần cứng, tùy thuộc vào hệ thống tệp bạn đang chạy (Linux), bạn có thể thử tắt ghi nhật ký hoặc ghi siêu dữ liệu cho DB để cải thiện hiệu suất một chút ở cấp hệ thống tệp. Bạn có thể làm một cái gì đó tương tự trên NTFS, nhưng điều này sẽ chỉ giúp bạn tăng thêm một chút. Điều này sẽ không được gấp đôi.

Bây giờ, điều thứ hai thứ hai ...

Giả sử bạn đã ở bên cạnh không có% thời gian nhưng CPU của bạn được chốt hoàn toàn bởi quy trình DB. Tùy chọn duy nhất của bạn bây giờ là giới thiệu nhiều máy DB (phân đoạn) và phân chia công việc.

Một lần nữa, bạn đã thực hiện với nghiên cứu của mình nếu đây là trường hợp. Không có gì bạn có thể làm để điều chỉnh CPU để đi nhanh hơn.

Cuối cùng, điều thứ ba ... thứ ba ...

Giả sử DB không làm gì nhiều. Sau đó, đi đến máy khách đang chạy chèn hàng loạt và kiểm tra tải CPU - nó có bị khóa không? Nếu vậy, kích hoạt thêm một số máy thực hiện cùng một đợt chèn chính xác và xem liệu bạn có thể có được một đoạn đường thẳng hay không.

Nếu CPU không được chốt, hãy khởi động thêm một số luồng trên cùng một máy cho đến khi nó được chốt và xem DB quy mô như thế nào.

Tôi nghĩ rằng bạn có thể đã thử điều đó, vì vậy tôi đoán là máy chủ khách của bạn đã được chốt (và nhiều luồng sẽ không tạo ra sự khác biệt) hoặc DB đã đạt đến giới hạn của nó và không thể mở rộng thêm nữa.

Phụ lục

Thực hiện chèn thô trên một bảng chưa được xử lý mà không có rác trong đó về cơ bản là một thao tác APPEND sẽ diễn ra nhanh như đĩa có thể xử lý việc ghi.

Tạo thêm các bảng trên cùng một máy chủ sẽ không có ích, nếu có bất cứ điều gì nó sẽ tăng tìm kiếm đĩa của bạn (để đến các bảng khác trên đĩa để nối thêm) và sẽ làm mọi thứ chậm lại.

Điều quan trọng là phải tìm ra nút cổ chai đó trước, sau đó chúng ta có thể tối ưu hóa địa ngục khỏi nó.

Mong rằng sẽ giúp! Giữ cho chúng tôi được đăng.


2
Tại sao bạn không đề cập đến awr hoặc statspack?
Phil 26/03/13

Với một gợi ý chắp thêm, tất cả trừ một trong những chủ đề đó sẽ không hoạt động do khóa độc quyền. Tôi không nghĩ rằng mã này đang ở giai đoạn hiệu quả khi cần phải điều chỉnh mức hệ thống - chính phương pháp này còn thiếu sót.
David Aldridge

Suy nghĩ xa hơn, tôi tin rằng cách tiếp cận của bạn có một lỗ hổng cơ bản. Nếu Viktor đã thử phương pháp chèn hàng loạt luồng đơn và có thời gian chờ i / o, điều đó có thể do phương thức chèn không hiệu quả và cam kết quá mức (chờ đồng bộ hóa tệp nhật ký). Bước quan trọng nhất phải là hiểu các cơ chế của Oracle và chọn một cơ chế phù hợp nhất trước tiên, chắc chắn?
David Aldridge

@DavidAldridge Người Viking làm rõ rằng anh ta đã vô hiệu hóa việc ghi nhật ký (và các chỉ số) cho rằng, tôi cho rằng DB không làm gì khác ngoài việc truyền dữ liệu được chèn ngay vào tệp bảng, đó là lý do tại sao tôi bắt anh ta phải nhìn vào Tôi / O chờ đợi. Có lẽ có nhiều Oracle đang làm điều đó nên / có thể bị vô hiệu hóa - đó là một điểm điều tra tốt, tôi không biết rõ về độ sâu của Oracle đủ để giúp đỡ điều đó không may.
Riyad Kalla

4

Gọi chèn đường dẫn trực tiếp với gợi ý chắp thêm khiến khóa độc quyền được thực hiện đối với toàn bộ bảng, do đó, việc có nhiều luồng thực hiện thao tác chèn sẽ không giúp ích gì. Bạn sẽ cần giải quyết một cách rõ ràng một phân vùng khác nhau với mỗi lần chèn ...

insert /*+ append */ into my_table partition (partition_name_1) ...

... Để có được các khóa độc quyền cấp phân vùng. Bạn sẽ không thể làm điều đó với một bảng được phân vùng vào ngày chèn, rất có thể, nhưng bạn có thể sử dụng phân vùng tổng hợp (không phải phân vùng) để có được nhiều phân vùng cho mỗi phạm vi ngày chèn duy nhất.

Không cam kết ở giữa các chèn, chỉ ở cuối.


Tôi có cần đề cập rõ tên phân vùng trong truy vấn không? Tôi có cột, loại sự kiện. Tôi sẽ cố gắng phân vùng theo nhóm các sự kiện và thực hiện sao cho mỗi luồng chỉ chèn một loạt các hàng thuộc loại cụ thể
adrift

Để tránh khóa độc quyền cấp bảng, có bạn làm.
David Aldridge

Gợi ý APPEND nên được bỏ qua bởi Oracle cho các chèn một hàng. Mô tả về quy trình của OP dường như ngụ ý hàng loạt hàng chèn. Tôi không chắc những người đó được đối xử như thế nào. Tôi đoán không có APPEND nhưng nó cần một số thử nghiệm.
Vincent Malgrat

Hmmm, đã không cân nhắc điều đó - thậm chí còn tệ hơn thế.
David Aldridge

Có đáng để thử chèn nhiều hàng với gợi ý APPEND không? Sau đó, tôi nên gửi bao nhiêu mục trên mỗi hàng nhiều hàng?
adrift
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.