Tôi cố gắng giải quyết vấn đề hiệu suất của ứng dụng của mình. Truy vấn Hibernate tạo ra, có dạng:Truy vấn từ ứng dụng Hibernate không sử dụng chỉ mục DB
select *
from (
select this.a, this.b, this.state, this.id
from view_user this
where this.state=:1 order by this.a asc, this.b
)
where rownum <= :2
nơi
- id là khóa chính
- có một kết hợp, chỉ số duy nhất trên (a, b, id).
- view_user có ~ 2 triệu mục
- view_user thực hiện một số tiếp tục tham gia vào các bảng khác
Issue
Các truy vấn trên thực - nhanh từ SQLDeveloper - nhanh chóng từ một ứng dụng Java nhỏ với hibernate - cực kỳ chậm (> 100x chậm hơn) từ ứng dụng với hibernate - giá trị cho các biến liên kết là 2 tương ứng 30 (nguồn gốc rownum từ phân trang) - truy vấn ngủ đông là "của biểu mẫu" ở trên. Thực tế có khoảng 20 cột trong chế độ xem.
trạng thái hiện tại của phân tích
- kế hoạch truy vấn cho thấy chỉ số được sử dụng khi truy vấn đến từ SQlDeveloper hoặc "ứng dụng java nhỏ".
- kế hoạch truy vấn cho thấy quét toàn bộ bảng được thực hiện nếu truy vấn đến từ ứng dụng ngủ đông
- Theo dõi DB chỉ hiển thị hai khác biệt: Cài đặt NLS (từ SQLDeveloper) và định dạng hơi khác (khoảng trắng). Mọi thứ khác có vẻ là như nhau ...
phiên bản
- ngủ đông: 2.1.8
- lái xe jdbc: sử dụng ojdbc14, 5 và 6. Làm cho có sự khác biệt
- Oracle : 10.2 và 11. Không tạo sự khác biệt
=> Tôi rất vui vì mọi gợi ý có thể liên quan đến vấn đề này. Điều rắc rối của tôi là việc truy tìm DB không cho thấy bất kỳ sự khác biệt nào ... Vâng, có vẻ như đó là điều gì đó về ngủ đông. Nhưng cái gì? Làm thế nào để phát hiện?
Vì lợi ích của sự hoàn chỉnh, đây truy vấn ngủ đông (từ nhật ký):
Select * from (
select this.USER_ID as USER_ID0_, this.CLIENT_ID as CLIENT_ID0_,
this.USER_NAME as USER_NAME0_, this.USER_FIRST_NAME as USER_FIR5_0_, this.USER_REMARKS as
USER_REM6_0_, this.USER_LOGIN_ID as USER_LOG7_0_, this.USER_TITLE as USER_TITLE0_,
this.user_language_code as user_lan9_0_, this.USER_SEX as USER_SEX0_,
this.USER_BIRTH_DATE as USER_BI11_0_, this.USER_TELEPHONE as USER_TE12_0_,
this.USER_TELEFAX as USER_TE13_0_, this.USER_MOBILE as USER_MO14_0_,
this.USER_EMAIL as USER_EMAIL0_, this.USER_ADDRESSLINE1 as USER_AD16_0_,
this.USER_ADDRESSLINE2 as USER_AD17_0_, this.USER_POSTALCODE as USER_PO18_0_,
this.USER_CITY as USER_CITY0_, this.USER_COUNTRY_CD as USER_CO20_0_,
this.USER_COUNTRY_NAME as USER_CO21_0_, this.USER_STATE_ID as USER_ST24_0_,
this.USER_STATE as USER_STATE0_, this.USER_TEMP_COLL_ID as USER_TE26_0_,
this.USER_TEMP_COLL_NAME as USER_TE27_0_, this.UNIT_ID as UNIT_ID0_,
this.CLIENT_NAME as CLIENT_38_0_, this.PROFILE_EXTID as PROFILE39_0_
from VIEW_USER this
where this.USER_STATE_ID=:1 order by this.USER_NAME asc, this.USER_FIRST_NAME asc
)
where rownum <= :2
chỉ số duy nhất là qua user_name, user_first_name, user_id.
Tôi nghi ngờ bạn có lỗi đánh máy trong truy vấn bạn đã nhập ở đây, vì lựa chọn bên trong có hai 'vị trí' trong đó. Có phải mệnh đề 'where rownum' thực sự ở bên ngoài được chọn không? – rejj
Bạn nói rằng "view_user có ~ 2 mục nhập mio". Vui lòng xác định "mio". Ngoài ra, các giá trị có thể có của view_user.state là gì và có bao nhiêu hàng cho mỗi giá trị có thể? Cuối cùng, những giá trị nào đang được cung cấp cho: 1 và: 2? Cảm ơn. –
sry, mio là triệu. Bộ hoàn trả của lựa chọn bên trong có thể là khoảng 80% của chế độ xem hoàn chỉnh (view_user) vì "this.state =: 1" với giá trị 2 cho: 1. –