Oracle
 sql >> база данни >  >> RDS >> Oracle

Адаптивната динамична статистика убива производителността в 12.1.0.2 RAC

След скорошна надстройка до 12.1.0.2, работих по редица проблеми с производителността. Много такива проблеми са свързани с лош SQL и редица проблеми, които разреших, доказах, че са проблеми в старата версия 11.2.0.4. Това просто означава, че винаги е бил проблем. Но хората се възползват от възможността на надстройката, за да ме накарат да поправя неща, които са били повредени от доста време.

Докато разглеждах проблемите с производителността, се натъкнах на два SQL оператора, които се превръщат в прасета в нашата система. Ето екранна снимка на двата SQL оператора, както се вижда в Lighty:

Можем да видим, че първият SQL израз (SQL ID 4b4wp0a8dvkf0) консумира процесора и чака четене от контролния файл. Вторият SQL израз (SQL ID frjd8zfy2jfdq) използва много CPU и има редица други събития за изчакване. Ето SQL текста на тези изрази.

SQL ID: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

SQL ID: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
    )
 
    )
 

И двете са част от новите функции за адаптивна оптимизация на заявки сега в 12c. По-конкретно, те се отнасят до частта за автоматична динамична статистика на тази функция. SQL ID frjd8zfy2jfdq е Oracle, получаващ информация за производителността на SQL изрази от GV$SQL. SQL ID 4b4wp0a8dvkf0 е Oracle, който получава същата информация за производителността на SQL изрази от таблиците с активна история на сесиите.

Bertand Drouvot обсъжда това в своя блог тук:https://bdrouvot.wordpress.com/2014/10/17/watch-out-for-optimizer_adaptive_features-as-it-may-have-a-huge-negative-impact/

Освен това участвах в сесия на Кристиан Антонини на Oak Table World 2015, където той спомена тези SQL изявления. Неговите слайдове от OTW са почти същите като тези:

http://www.soug.ch/fileadmin/user_upload/SIGs/SIG_150521_Tuning_R/Christian_Antognini_AdaptiveDynamicSampling_trivadis.pdf

Тези връзки по-горе и бележките на MOS, които посочвам по-долу, предоставят голяма част от основата на информацията, която представям тук.

Всички функции за адаптивна оптимизация на заявки трябва да направят живота на DBA по-добър. Те трябва да помогнат на оптимизатора да взема по-добри решения, дори след като SQL оператор е започнал да се изпълнява. В този конкретен случай тези заявки трябва да помогнат на CBO да получи по-добра статистика, дори ако статистиката липсва. Това може да помогне за подобряване на производителността на SQL, но както открих в моя случай, това пречи на цялостната производителност на системата.

За повече информация относно адаптивната оптимизация на заявки вижте бележка 2031605.1. Това ще ви отведе до други бележки, но по-специално до тази дискусия, Бележка 2002108.1 Автоматична динамична статистика.

Влошава нещата, че моята производствена система, която вижда това поведение, е Oracle RAC. Когато SQL ID frjd8zfy2jfdq се изпълнява на Oracle RAC системи, се използва паралелна заявка, което е очевидно от моя екранна снимка от enq:PS – конкуренция и „PX%“ чакащи събития.

Можем да включим динамичното вземане на проби, както следва:

променете системния набор optimizer_dynamic_sampling=0 обхват=и двете;

Стойността по подразбиране на този параметър е 2.

За мен тези заявки консумират ресурси и влияят върху цялостната производителност на базата данни. И все пак тези функции са предназначени да подобрят производителност. Винаги има риск, че ако изключа функцията, за да помогна на производителността в една област, това ще навреди на производителността в друга област. Но тъй като optimizer_dynamic_sampling<>11 за мен, аз не използвам тази функция докрай, така че не получавам всички предимства, които бих могъл да имам. Освен това нашият код не разчита на динамично вземане на проби. Така че е безопасно за мен да изключа това.

След промяна на параметъра можех да видя незабавна промяна, както е показано по-долу.

Червената линия показва часа, в който направих промяната. Ясно е, че ASH версията на тази заявка вече не се изпълнява. Версията на V$SQL все още се изпълнява, но вече не вижда събития за изчакване на паралелна заявка. Сега най-вече само консумира процесора. Считам този напредък, но не и пълно решение.

Като странична забележка, можех да изключа всички функции за адаптивно оптимизиране на заявки със следното:

alter system set optimizer_adaptive_features=false scope=both;

Но знам, че имам заявки, които се наслаждават на адаптивната оптимизация на присъединяването и не искам да изключвам всичко, а само динамично вземане на проби.

И така, какво да правим със SQL ID frjd8zfy2jfdq? Да видим дали можем да разрешим оставащия проблем. От една от MOS бележките, които свързах по-горе, знам, че можем да зададем този скрит параметър:

alter system set "_optimizer_dsdir_usage_control"=0 scope=both;

Стойността по подразбиране за този скрит параметър беше 126 в моята система 12.1.0.2. Намерих настройката по подразбиране със следното:

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;

Тази стойност е важна в случай, че искам да я задам обратно, без да се налага да изваждам параметъра от SPFILE, което ще изисква престой.

Сега мога да продължа с промяната на този скрит параметър и да го настроя на нула. Ето как изглежда този SQL израз в Lighty след промяната:

Изглежда, че „мисията е изпълнена“ в спирането на изпълнението на тези два SQL оператора.

Тези, които работят с 12.1.0.2 на Oracle RAC, може да искат да проверят дали тези два SQL оператора не причиняват собствени проблеми с производителността.

Това изглежда е един от онези случаи, когато функция, която трябва да помогне на производителността, всъщност прави обратното.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Модулът на Python cx_Oracle модулът не можа да бъде намерен

  2. Как да проверите максималния брой разрешени връзки към база данни на Oracle?

  3. Агрегат на Oracle за свързване на низове със запетая и за писане на персонализирани агрегати

  4. изтрийте дублиращи се редове от Oracle

  5. Грешка при добавяне на режим на готовност