2014-05-23 22 views
5

Một chương trình java đang thực hiện chèn số lượng lớn vào bảng Oracle. Nó hoạt động tốt cho 100-200 hồ sơ nhưng nó treo cho hơn 4000 hồ sơ.Tại sao INSERT/* + APPEND */được sử dụng?

Khi tôi đã kiểm tra truy vấn, nó có INSERT /*+APPEND*/ trong đó.

INSERT /*+APPEND*/ là gì và tại sao nó được sử dụng trong truy vấn INSERT? Chương trình có treo vì điều này không?

+0

/* + APPEND */Tôi nghĩ đó chỉ là nhận xét. –

+6

[Gợi ý này được giải thích trong tài liệu] (http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements006.htm#sthref495). Bạn có nhiều quá trình chèn cùng một lúc hoặc dữ liệu không được cam kết trong bảng không? –

+0

@AlexPoole Có, Nhiều chủ đề đang truy cập vào bảng cùng một lúc –

Trả lời

4

Đó là gợi ý trình tối ưu hóa SQL. Trong trường hợp của bạn rất có thể nó không có tác động. Có lẽ đó là một tối ưu hóa sớm.

Gợi ý này nên thực thi được gọi là chèn đường dẫn trực tiếp, bỏ qua bộ đệm đệm của Oracle và ghi dữ liệu trực tiếp vào tệp dữ liệu. Dữ liệu được nối thêm vượt quá vạch dấu nước cao (HWM) - bỏ qua bản đồ không gian trống của bảng, không có trình kích hoạt nào được kích hoạt và không có dấu kiểm nào được kiểm tra. Mặt khác, loại chèn này đang chặn. Chỉ một phiên có thể sử dụng nó trên một bảng cụ thể cùng một lúc.

Một đoạn trích từ tài liệu:

"Các gợi ý APPEND chỉ được hỗ trợ với cú pháp subquery của báo cáo kết quả INSERT, không phải là mệnh đề VALUES Nếu bạn chỉ định APPEND gợi ý với mệnh đề VALUES, nó. bị bỏ qua và chèn thông thường sẽ được sử dụng. để sử dụng trực tiếp con đường INSERT với mệnh đề VALUES, tham khảo để "APPEND_VALUES gợi ý" gợi ý này chỉ có tác dụng khi bạn sử dụng INSERT như SELECT tuyên bố

insert into <table> SELECT * FROM .... 

Khi bạn chèn các giá trị, Oracle sẽ bỏ qua nó. Các phiên bản Oracle mới hơn cũng hỗ trợ gợi ý APPEND_VALUES.

Nếu bạn muốn xác thực gợi ý đang được sử dụng mở Toad hoặc SQL Developer, hãy chọn trình duyệt phiên, tìm phiên cụ thể đó và SQL hiện tại và kế hoạch thực hiện. Khi bạn nhìn thấy trong kế hoạch exec một cái gì đó như "INSERT into TABLE CONVENTIONAL" sau đó gợi ý được bỏ qua. Nếu bạn thấy "INSERT as SELECT" thì bạn đang sử dụng tải đường dẫn trực tiếp.

+0

"Gợi ý này chỉ hoạt động khi bạn sử dụng INSERT làm câu lệnh SELECT". Bạn có chắc nó chỉ hoạt động trong trường hợp này? –

+2

Tôi nghĩ nó giống như vậy. Mở Toad hoặc SQL Developer, chọn trình duyệt phiên, tìm phiên cụ thể đó và đó là SQL hiện tại và kế hoạch thực hiện. Khi bạn nhìn thấy trong kế hoạch thực hiện một cái gì đó giống như "INSERT vào TABLE CONVENTIONAL" thì gợi ý bị bỏ qua. Nếu bạn thấy "INSERT as SELECT" thì bạn đang sử dụng tải đường dẫn trực tiếp. – ibre5041

+3

Đoạn trích từ tài liệu: "Gợi ý PHỤ LỤC chỉ được hỗ trợ với cú pháp truy vấn phụ của câu lệnh INSERT, không phải mệnh đề VALUES. Nếu bạn chỉ định gợi ý PHỤ LỤC với mệnh đề VALUES, thì bỏ qua và chèn thông thường sẽ được sử dụng. INSERT đường dẫn trực tiếp với mệnh đề VALUES, tham khảo "APPEND_VALUES Gợi ý". " – ibre5041

3

insert thường tìm kiếm không gian trống đầu tiên trong bảng của bạn để thêm bản ghi mới. Trong khi điều này bảo tồn không gian, đôi khi nó có thể làm chậm hoạt động.

/*+APPEND*/hint gây ra tuyên bố insert luôn luôn, tốt, vì thiếu thuật ngữ tốt hơn, hãy thêm hàng mới được chèn vào cuối bảng. Điều này có thể lãng phí một số không gian, nhưng thường nhanh hơn. Điều này đặc biệt hữu ích nếu bạn biết bạn không có quá nhiều vùng trống ở giữa bảng (nghĩa là bạn không thực hiện nhiều số lượng delete s và update giây trên đó).

+2

Gợi ý PHỤ LỤC sẽ chỉ làm giảm tạo lại nếu bảng [khoảng trắng] được đặt thành NOLOGGING hoặc DB ở chế độ NOARCHIVELOG. oracle-base.com/articles/misc/append-hint.php – user584583

1

Đây là gợi ý trình biên dịch ORACLE. Nó có cho một mục đích và không phải là một bình luận. Gợi ý này được sử dụng ở đó để tăng tốc độ chèn, vì vậy tôi không nghĩ rằng đó là nguyên nhân gây treo chương trình.

Tuy nhiên, xin hỏi dba của bạn để kiểm tra dung lượng trống trong tablespace bảng này đang sử dụng. (Dba của bạn sẽ hiểu tuyên bố này tốt hơn :))

Có thể có một vấn đề mà có rất ít không gian có sẵn cho bất kỳ chèn thêm nào trong vùng bảng đó, mà dba sẽ có thể giải quyết.

Tại sao có ít không gian hơn? bởi vì gợi ý APPEND lãng phí không gian như được giải thích bởi câu trả lời ở trên bởi @Mureinik, và có thể là một vấn đề nếu có quá nhiều lần chèn thường xuyên với gợi ý này trong bảng đó.

0

Tôi không biết về "tăng tốc" chèn, nhưng tôi đã chắc chắn tìm thấy gợi ý, và có, đây là những gì Oracle gọi nó - không phải là một bình luận - cực kỳ hữu ích cho việc duy trì thứ tự các bản ghi khi tôi làm một chèn từ một bảng vào khác, khi tôi ghép lệnh với một ORDER BY ở cuối:

INSERT /*+ append */ INTO MYAPP.COUNTRIES (ID, CODE, NAME) 
SELECT ID, CODE, NAME FROM MYAPP.OLD_COUNTRIES_TABLE ORDER BY NAME ASC; 
COMMIT; 

tôi đã nhận được Flack rằng đây chỉ là một trùng hợp ngẫu nhiên (xem this thread trên SO), nhưng tôi đã sử dụng nó nhiều lần, bây giờ, và đó là ít nhất là trái cây tôi kết thúc với. Nếu bạn sử dụng INSERT với ORDER BY, nhưng mà không có gợi ý chắp thêm, thì ORDER BY bị bỏ qua và hoàn toàn vô dụng để đảm bảo các bản ghi có thể được truy lục theo thứ tự chúng được chèn vào (xem my proof in my answer, here).

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