Sau khi nâng cấp gần đây lên 12.1.0.2, tôi đã khắc phục một số vấn đề về hiệu suất. Nhiều vấn đề như vậy liên quan đến SQL kém và một số vấn đề tôi đã giải quyết mà tôi đã chứng minh là các vấn đề trong bản phát hành 11.2.0.4 cũ. Điều này chỉ có nghĩa là nó luôn là một vấn đề. Nhưng mọi người đang tận dụng cơ hội nâng cấp để yêu cầu tôi sửa chữa những thứ đã bị hỏng trong một thời gian dài.
Trong khi xem xét các vấn đề về hiệu suất, tôi đã bắt gặp hai câu lệnh SQL đang trở thành con lợn trong hệ thống của chúng tôi. Đây là ảnh chụp màn hình của hai câu lệnh SQL như trong Lighty:
Chúng ta có thể thấy rằng câu lệnh SQL đầu tiên (SQL ID 4b4wp0a8dvkf0) đang tiêu thụ CPU và chờ đọc từ Tệp điều khiển. Câu lệnh SQL thứ hai (SQL ID frjd8zfy2jfdq) đang sử dụng nhiều CPU và cũng có một số sự kiện chờ khác. Đây là văn bản SQL của các câu lệnh này.
ID SQL:frjd8zfy2jfdq
SELECT
executions
,end_of_fetch_count
,elapsed_time / px_servers elapsed_time
,cpu_time / px_servers cpu_time
,buffer_gets / executions buffer_gets
FROM
(
SELECT
SUM (executions) AS executions
,SUM (
CASE
WHEN px_servers_executions > 0
THEN px_servers_executions
ELSE executions
END
) AS px_servers
,SUM (end_of_fetch_count) AS end_of_fetch_count
,SUM (elapsed_time) AS elapsed_time
,SUM (cpu_time) AS cpu_time
,SUM (buffer_gets) AS buffer_gets
FROM
gv$sql
WHERE
executions > 0
AND sql_id = : 1
AND parsing_schema_name = : 2
ID SQL:4b4wp0a8dvkf0
SELECT
executions
,end_of_fetch_count
,elapsed_time / px_servers elapsed_time
,cpu_time / px_servers cpu_time
,buffer_gets / executions buffer_gets
FROM
(
SELECT
SUM (executions_delta) AS EXECUTIONS
,SUM (
CASE
WHEN px_servers_execs_delta > 0
THEN px_servers_execs_delta
ELSE executions_delta
END
) AS px_servers
,SUM (end_of_fetch_count_delta) AS end_of_fetch_count
,SUM (elapsed_time_delta) AS ELAPSED_TIME
,SUM (cpu_time_delta) AS CPU_TIME
,SUM (buffer_gets_delta) AS BUFFER_GETS
FROM
DBA_HIST_SQLSTAT s
,V$DATABASE d
,DBA_HIST_SNAPSHOT sn
WHERE
s.dbid = d.dbid
AND bitand (
nvl (
s.flag
,0
)
,1
) = 0
AND sn.end_interval_time > (
SELECT
systimestamp AT TIME ZONE dbtimezone
FROM
dual
) - 7
AND s.sql_id = : 1
AND s.snap_id = sn.snap_id
AND s.instance_number = sn.instance_number
AND s.dbid = sn.dbid
AND parsing_schema_name = : 2
)
)
Cả hai điều này đều là một phần của các tính năng Tối ưu hóa truy vấn thích ứng mới hiện có trong 12c. Cụ thể hơn, những điều này liên quan đến phần Thống kê động tự động của tính năng này. SQL ID frjd8zfy2jfdq là Oracle lấy thông tin về hiệu suất câu lệnh SQL từ GV $ SQL. SQL ID 4b4wp0a8dvkf0 là Oracle lấy cùng một thông tin về hiệu suất câu lệnh SQL từ các bảng Lịch sử phiên hoạt động.
Bertand Drouvot thảo luận điều này trên blog của anh ấy tại đây:https://bdrouvot.wordpress.com/2014/10/17/watch-out-for-optimizer_adaptive_features-as-it-may-have-a-huge-negative-impact/
Ngoài ra, tôi đã tham gia một phiên của Christian Antognini tại Oak Table World 2015, nơi anh ấy đã đề cập đến các câu lệnh SQL này. Các trang trình bày của anh ấy từ OTW khá giống như sau:
http://www.soug.ch/fileadmin/user_upload/SIGs/SIG_150521_Tuning_R/Christian_Antognini_AdaptiveDynamicSampling_trivadis.pdf
Những liên kết ở trên và Ghi chú MOS mà tôi tham khảo bên dưới cung cấp phần lớn cơ sở của thông tin tôi trình bày ở đây.
Tất cả các tính năng Tối ưu hóa truy vấn thích ứng được cho là sẽ làm cho cuộc sống của DBA tốt hơn. Chúng phải giúp Trình tối ưu hóa đưa ra quyết định tốt hơn, ngay cả sau khi câu lệnh SQL đã bắt đầu thực thi. Trong trường hợp cụ thể này, những truy vấn này được cho là sẽ giúp CBO có được số liệu thống kê tốt hơn, ngay cả khi số liệu thống kê bị thiếu. Điều này có thể giúp cải thiện hiệu suất SQL, nhưng như tôi nhận thấy trong trường hợp của mình, nó đang cản trở hiệu suất tổng thể của hệ thống.
Để biết thêm về Tối ưu hóa Truy vấn Thích ứng, hãy xem Lưu ý 2031605.1. Điều này sẽ dẫn bạn đến các ghi chú khác, nhưng cụ thể là thảo luận này, Ghi chú 2002108.1 Thống kê động tự động.
Làm cho vấn đề tồi tệ hơn là hệ thống sản xuất của tôi có hành vi này là Oracle RAC. Khi SQL ID frjd8zfy2jfdq được thực hiện trên hệ thống Oracle RAC, truy vấn song song được sử dụng, điều này có thể thấy rõ từ ảnh chụp màn hình của tôi bởi enq:PS - contention và các sự kiện chờ “PX%”.
Chúng ta có thể chuyển đổi lấy mẫu động như sau:
thay đổi bộ tối ưu hóa hệ thống_dynamic_sampling =0 scope =cả hai;
Giá trị mặc định của tham số này là 2.
Đối với tôi, những truy vấn này đang tiêu tốn tài nguyên và ảnh hưởng đến hiệu suất cơ sở dữ liệu tổng thể. Tuy nhiên, những tính năng này được thiết kế để cải thiện màn biểu diễn. Luôn có rủi ro là nếu tôi tắt tính năng trợ giúp hiệu suất ở một khu vực, nó sẽ ảnh hưởng đến hiệu suất ở khu vực khác. Nhưng vì tôi đã tối ưu hóa tính năng tối ưu hóa <> 11 nên tôi không sử dụng hết tính năng đó nên tôi sẽ không thu được tất cả lợi ích mà tôi có thể có được. Ngoài ra, mã của chúng tôi không dựa vào lấy mẫu động để xảy ra. Vì vậy, tôi thấy an toàn nếu tắt tính năng này.
Sau khi thay đổi thông số, tôi có thể thấy sự thay đổi ngay lập tức như hình dưới đây.
Đường màu đỏ cho biết thời gian tôi thực hiện thay đổi. Rõ ràng là phiên bản ASH của truy vấn này không còn thực thi nữa. Phiên bản V $ SQL vẫn đang thực thi nhưng không còn thấy các sự kiện chờ truy vấn song song. Bây giờ hầu như chỉ tiêu tốn CPU. Tôi coi đây là tiến bộ, nhưng không phải là giải pháp đầy đủ.
Xin lưu ý thêm, tôi có thể đã tắt tất cả các tính năng Tối ưu hóa truy vấn thích ứng bằng cách sau:
alter system set optimizer_adaptive_features=false scope=both;
Nhưng tôi biết rằng tôi có các truy vấn “tận hưởng” tính năng Tối ưu hóa tham gia thích ứng và tôi không muốn tắt tất cả, chỉ lấy mẫu động.
Vậy bây giờ phải làm gì với SQL ID frjd8zfy2jfdq? Hãy xem liệu chúng ta có thể giải quyết vấn đề còn lại hay không. Từ một trong các Ghi chú MOS mà tôi đã liên kết ở trên, tôi biết rằng chúng ta có thể đặt thông số ẩn này:
alter system set "_optimizer_dsdir_usage_control"=0 scope=both;
Giá trị mặc định cho tham số ẩn này là 126 trong hệ thống 12.1.0.2 của tôi. Tôi đã tìm thấy cài đặt mặc định như sau:
select a.ksppinm name, b.ksppstvl value, b.ksppstdf deflt,
from
sys.x$ksppi a,
sys.x$ksppcv b
where a.indx = b.indx
and a.ksppinm like '\_%' escape '\'
and a.ksppinm like '%dsdir%'
order by name;
Giá trị này rất quan trọng trong trường hợp tôi muốn đặt lại nó mà không phải lấy tham số ra khỏi SPFILE, điều này sẽ yêu cầu thời gian ngừng hoạt động.
Bây giờ tôi có thể tiến hành thay đổi thông số ẩn này và đặt nó thành 0. Đây là cách câu lệnh SQL đó trông như thế nào trong Lighty sau khi thay đổi:
Có vẻ như "nhiệm vụ đã hoàn thành" trong việc ngăn hai câu lệnh SQL đó thực thi.
Những người đang chạy 12.1.0.2 trên Oracle RAC có thể muốn xác minh rằng hai câu lệnh SQL này không gây ra sự cố hiệu suất của riêng chúng.
Đây dường như là một trong những trường hợp mà một tính năng được cho là giúp hiệu suất thực sự lại làm ngược lại.