2009-10-06 34 views
8

Tôi đang chạy truy vấn đối với Oracle 10g với JDBC (sử dụng trình điều khiển mới nhất và UCP làm DataSource) để truy xuất CLOB (ký tự đại diện 20k). Tuy nhiên, hiệu suất có vẻ khá tệ: việc thu hồi hàng loạt 100 LOB mất trung bình 4 s. Các hoạt động cũng không phải là I/O cũng như CPU ​​và mạng lưới không bị ràng buộc đánh giá từ các quan sát của tôi.Hiệu suất CLOB Oracle

thiết lập thử nghiệm của tôi trông như thế này:

PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource(); 
dataSource.setConnectionFactoryClassName("..."); 
dataSource.setConnectionPoolName("..."); 
dataSource.setURL("..."); 
dataSource.setUser("..."); 
dataSource.setPassword("..."); 

dataSource.setConnectionProperty("defaultRowPrefetch", "1000"); 
dataSource.setConnectionProperty("defaultLobPrefetchSize", "500000"); 

final LobHandler handler = new OracleLobHandler(); 
JdbcTemplate j = new JdbcTemplate(dataSource); 

j.query("SELECT bigClob FROM ...", 

     new RowCallbackHandler() { 

      public void processRow(final ResultSet rs) throws SQLException { 

       String result = handler.getClobAsString(rs, "bigClob"); 

      } 

     }); 

} 

tôi đã thử nghiệm với lấy kích cỡ nhưng không có kết quả. Tôi có làm điều gì sai? Có cách nào để tăng tốc độ truy xuất CLOB khi sử dụng JDBC không?

+0

Bạn xác định nó không bị ràng buộc mạng như thế nào? Bạn đang nói về việc thiết lập một kết nối JDBC mới (đắt tiền), 2Mb giá trị dữ liệu để đọc từ đĩa, gửi nó qua mạng và phí trên của truy vấn (không được chỉ định). Tôi không biết nếu 4s là tất cả những gì xấu tùy thuộc vào cách bố trí mạng của bạn và thiết lập cơ sở dữ liệu. – Gandalf

+0

Làm rõ: Tôi đo bằng * đơn vị * 100 vì vậy hình phạt ban đầu của kết nối không được tính. Tổng thông lượng mạng ở dưới 2Mbit/s vì vậy tôi cho rằng nó không phải là mạng bị ràng buộc. – yawn

+0

Truy vấn thực tế mất bao lâu? – Gandalf

Trả lời

2

Cảm ơn tất cả các đề xuất hữu ích. Mặc dù bị gắn cờ là câu trả lời cho vấn đề câu trả lời của tôi là dường như không có giải pháp tốt. Tôi đã thử sử dụng các câu lệnh song song, các đặc tính lưu trữ khác nhau, các temp được sắp xếp trước. bàn và những thứ khác. Các hoạt động dường như không được ràng buộc với bất kỳ đặc trưng có thể nhìn thấy thông qua dấu vết hoặc giải thích kế hoạch. Ngay cả truy vấn song song dường như là sơ sài khi CLOB có liên quan.

Chắc chắn sẽ có các tùy chọn tốt hơn để xử lý với các CLOB lớn (đặc biệt là nén) trong môi trường 11g nhưng atm. Tôi bị mắc kẹt với 10g.

Tôi đã chọn tham gia một vòng bổ sung cho cơ sở dữ liệu, trong đó tôi sẽ xử lý trước các CLOB thành một định dạng nhị phân được tối ưu hóa RAW. Trong các lần triển khai trước, điều này luôn là một lựa chọn rất nhanh và có khả năng sẽ đáng giá khi gặp khó khăn trong việc duy trì bộ nhớ cache được tính toán ngoại tuyến. Bộ nhớ cache sẽ được thương lượng và cập nhật bằng cách sử dụng một quy trình liên tục và AQ cho đến khi có ai đó đưa ra ý tưởng tốt hơn.

+0

Trông giống như cách giải quyết tốt như thể bạn lấy 100 hàng, bạn sẽ trả thêm tiền cho chuyến đi nhưng tiết kiệm 100 chuyến khứ hồi, hoàn toàn bạn tiết kiệm được 100-1 = 99 chuyến đi khứ hồi. Nhưng làm thế nào bạn thực hiện nó? – user451795

+0

Bằng cách tìm nạp chỉ CLOB + một số khóa để nhận dạng chúng sau này và ghi chúng vào một kho khóa-giá trị cục bộ. Tôi đã sử dụng [Oracle Berkeley DB] (http://www.oracle.com/technetwork/database/berkeleydb/overview/index.html) nhưng bạn có thể dễ dàng sử dụng SQLite hoặc bất cứ điều gì khác mà tôi cho là. – yawn

6

tổng Kích thước của tập kết quả là trong hàng vạn - đo trong khoảng thời gian toàn bộ thu hồi các chi phí ban đầu

Có một Sắp xếp theo trong truy vấn? 10K hàng là khá nhiều nếu nó phải được sắp xếp.

Ngoài ra, truy xuất PK không phải là một thử nghiệm hợp lý so với truy xuất toàn bộ CLOB. Oracle lưu trữ các hàng trong bảng có thể có nhiều trong một khối, nhưng mỗi CLOB (nếu chúng> 4K) sẽ được lưu trữ ngoài dòng, mỗi hàng trong một khối các khối. Vì vậy, việc quét danh sách các PK sẽ nhanh chóng. Ngoài ra, có thể có một chỉ mục trên PK, vì vậy Oracle có thể nhanh chóng quét các khối chỉ mục và thậm chí không truy cập vào bảng.

4 giây có vẻ hơi cao, nhưng đó là 2MB cần được đọc từ đĩa và được chuyển qua mạng tới chương trình Java của bạn. Mạng có thể là một vấn đề. Nếu bạn thực hiện một dấu vết SQL của phiên nó sẽ chỉ cho bạn chính xác nơi mà thời gian đang được chi tiêu (đọc đĩa hoặc mạng).

5

Trải nghiệm quá khứ của tôi về việc sử dụng dữ liệu loại LOB oracle để lưu trữ dữ liệu lớn chưa được tốt. Nó là tốt khi nó là dưới 4k kể từ khi nó lưu trữ nó tại địa phương như varchar2. Khi nó vượt quá 4k, bạn bắt đầu thấy hiệu suất suy giảm. Có lẽ, mọi thứ có thể đã được cải thiện kể từ lần cuối tôi thử cách đây vài năm, nhưng đây là những thứ tôi đã tìm thấy trong quá khứ để biết thông tin của bạn:

Vì khách hàng cần nhận LOB thông qua máy chủ oracle, bạn có thể xem xét những điều sau tình huống thú vị.

  • dữ liệu lob sẽ cạnh tranh giới hạn SGA bộ nhớ cache với loại dữ liệu khác nếu oracle quyết định lưu vào bộ nhớ cache. Vì dữ liệu dấu mũ là chung chung, do đó, nó có thể đẩy các dữ liệu khác
  • lob đọc đĩa kém nếu oracle quyết định không lưu vào bộ nhớ cache và truyền dữ liệu cho khách hàng.
  • phân mảnh có thể là một cái gì đó mà bạn chưa gặp phải. Bạn sẽ thấy nếu ứng dụng của bạn xóa thùy, và oracle cố gắng tái sử dụng thùy. Tôi không biết liệu có hỗ trợ oracle trực tuyến chống phân mảnh đĩa cho lob (chúng có chỉ mục hay không, nhưng phải mất nhiều thời gian khi chúng tôi thử nó trước đó).

Bạn đã đề cập 4 cho 100 thùy của avg 20k, vì vậy nó là 40ms mỗi thùy. Hãy nhớ rằng mỗi lob cần phải lấy thông qua locater Lob riêng biệt (nó không nằm trong tập kết quả theo mặc định). Đó là một chuyến đi vòng bổ sung cho mỗi lob, tôi giả định (Tôi không chắc chắn 100% về điều này vì nó đã được một thời gian trước đây) Nếu đó là trường hợp, tôi giả định rằng sẽ có ít nhất 5ms thêm thời gian cho mỗi chuyến đi vòng theo thứ tự nối tiếp , đúng? Nếu vậy, hiệu suất của bạn đã được giới hạn đầu tiên bởi các lần tìm nạp liên tiếp.Bạn sẽ có thể xác minh điều này bằng cách theo dõi thời gian dành cho việc thực hiện sql so với việc tìm nạp nội dung lob. Hoặc bạn có thể xác minh điều này bằng cách loại trừ cột lob như được đề xuất bởi câu trả lời trước đó trong bài đăng, điều này sẽ cho bạn biết liệu đó có phải là liên quan đến lob hay không.

Chúc may mắn

3

Tôi đã gặp vấn đề tương tự và tìm thấy Tôm hùm của JDBC thực hiện cuộc gọi mạng khi truy cập vào các thùy.

Với trình điều khiển JDBC Oracle 11.2g, bạn có thể sử dụng tìm nạp trước. Điều này tăng tốc truy cập lên 10 lần ...

statement1.setFetchSize(1000); 
if (statement1 instanceof OracleStatement) { 
    ((OracleStatement) statement1).setLobPrefetchSize(250000); 
} 
Các vấn đề liên quan