Penyesuaian kinerja dan pemecahan masalah basis data hari ini

Sayangnya, sekarang peran spesialis dalam Penyesuaian kinerja dan pemecahan masalah basis data hanya dikurangi hingga yang terakhir - pemecahan masalah: mereka hampir selalu beralih ke spesialis hanya ketika masalah telah mencapai titik kritis, dan mereka perlu dipecahkan "kemarin". Dan bahkan jika itu baik jika mereka berbalik, dan jangan menunda masalah dengan membeli perangkat keras yang lebih mahal dan kuat tanpa audit kinerja yang terperinci dan stress test. Memang, frustrasi sering kali cukup: mereka membeli peralatan bernilai 2-5 kali lebih mahal, dan hanya menang 30-40% dalam kinerja, seluruh peningkatan yang dimakan dalam beberapa bulan baik oleh peningkatan jumlah pengguna, atau oleh peningkatan eksponensial dalam data, ditambah dengan komplikasi logika.

Dan sekarang, pada saat jumlah arsitek, penguji dan insinyur DevOps berkembang pesat, dan pengembang Java Core bahkan mengoptimalkan bekerja dengan string , perlahan tapi pasti saatnya tiba untuk pengoptimal database. DBMS dengan setiap rilis menjadi lebih cerdas dan lebih kompleks sehingga mempelajari nuansa dan optimisasi baik yang terdokumentasi maupun tidak berdokumen membutuhkan banyak waktu. Sejumlah besar artikel diterbitkan setiap bulan dan konferensi besar yang ditujukan untuk Oracle diadakan. Maaf untuk analogi dangkal, tetapi dalam situasi ini, ketika administrator basis data menjadi serupa dengan pilot pesawat dengan sakelar, tombol, lampu, dan layar yang tak terhitung jumlahnya, sudah tidak pantas memuatnya dengan seluk-beluk optimasi kinerja.

Tentu saja, DBA, seperti pilot, dalam banyak kasus dapat dengan mudah memecahkan masalah yang jelas dan sederhana ketika mereka mudah didiagnosis atau terlihat di berbagai "puncak" (Top events, SQL top, segmen atas ...). Dan yang mudah ditemukan di MOS atau Google, meskipun mereka tidak tahu solusinya. Jauh lebih rumit ketika gejala-gejalanya tersembunyi di balik kompleksitas sistem dan gejala-gejala tersebut perlu ditangkap di antara sejumlah besar informasi diagnostik yang dikumpulkan oleh Oracle DBMS itu sendiri.

Salah satu contoh yang paling sederhana dan paling jelas adalah analisis filter dan prediksi akses: dalam sistem besar dan sarat, sering terjadi bahwa masalah seperti itu mudah diabaikan, karena beban tersebar cukup merata pada permintaan yang berbeda (dengan bergabung untuk berbagai tabel, dengan sedikit perbedaan kondisi, dll.), dan segmen atas tidak menunjukkan sesuatu yang istimewa, mereka berkata, "baik, ya, dari tabel ini data paling sering diperlukan dan ada lebih banyak" . Dalam kasus seperti itu, Anda dapat memulai analisis dengan statistik dari SYS.COL_USAGE $: col_usage.sql

col owner format a30 col oname format a30 heading "Object name" col cname format a30 heading "Column name" accept owner_mask prompt "Enter owner mask: "; accept tab_name prompt "Enter tab_name mask: "; accept col_name prompt "Enter col_name mask: "; SELECT a.username as owner ,o.name as oname ,c.name as cname ,u.equality_preds as equality_preds ,u.equijoin_preds as equijoin_preds ,u.nonequijoin_preds as nonequijoin_preds ,u.range_preds as range_preds ,u.like_preds as like_preds ,u.null_preds as null_preds ,to_char(u.timestamp, 'yyyy-mm-dd hh24:mi:ss') when FROM sys.col_usage$ u , sys.obj$ o , sys.col$ c , all_users a WHERE a.user_id = o.owner# AND u.obj# = o.obj# AND u.obj# = c.obj# AND u.intcol# = c.col# AND a.username like upper('&owner_mask') AND o.name like upper('&tab_name') AND c.name like upper('&col_name') ORDER BY a.username, o.name, c.name ; col owner clear; col oname clear; col cname clear; undef tab_name col_name owner_mask; 

Namun, untuk analisis lengkap informasi ini tidak cukup, karena tidak menunjukkan kombinasi predikat. Dalam hal ini, analisis v $ active_session_history dan v $ sql_plan dapat membantu kami:

 with ash as ( select sql_id ,plan_hash_value ,table_name ,alias ,ACCESS_PREDICATES ,FILTER_PREDICATES ,count(*) cnt from ( select h.sql_id ,h.SQL_PLAN_HASH_VALUE plan_hash_value ,decode(p.OPERATION ,'TABLE ACCESS',p.OBJECT_OWNER||'.'||p.OBJECT_NAME ,(select i.TABLE_OWNER||'.'||i.TABLE_NAME from dba_indexes i where i.OWNER=p.OBJECT_OWNER and i.index_name=p.OBJECT_NAME) ) table_name ,OBJECT_ALIAS ALIAS ,p.ACCESS_PREDICATES ,p.FILTER_PREDICATES -- ,         : -- ,h.sql_plan_operation -- ,h.sql_plan_options -- ,decode(h.session_state,'ON CPU','ON CPU',h.event) event -- ,h.current_obj# from v$active_session_history h ,v$sql_plan p where h.sql_opname='SELECT' and h.IN_SQL_EXECUTION='Y' and h.sql_plan_operation in ('INDEX','TABLE ACCESS') and p.SQL_ID = h.sql_id and p.CHILD_NUMBER = h.SQL_CHILD_NUMBER and p.ID = h.SQL_PLAN_LINE_ID --     3 : -- and h.sample_time >= systimestamp - interval '3' hour ) --       : -- where table_name='&OWNER.&TABNAME' group by sql_id ,plan_hash_value ,table_name ,alias ,ACCESS_PREDICATES ,FILTER_PREDICATES ) ,agg_by_alias as ( select table_name ,regexp_substr(ALIAS,'^[^@]+') ALIAS ,listagg(ACCESS_PREDICATES,' ') within group(order by ACCESS_PREDICATES) ACCESS_PREDICATES ,listagg(FILTER_PREDICATES,' ') within group(order by FILTER_PREDICATES) FILTER_PREDICATES ,sum(cnt) cnt from ash group by sql_id ,plan_hash_value ,table_name ,alias ) ,agg as ( select table_name ,'ALIAS' alias ,replace(access_predicates,'"'||alias||'".','"ALIAS".') access_predicates ,replace(filter_predicates,'"'||alias||'".','"ALIAS".') filter_predicates ,sum(cnt) cnt from agg_by_alias group by table_name ,replace(access_predicates,'"'||alias||'".','"ALIAS".') ,replace(filter_predicates,'"'||alias||'".','"ALIAS".') ) ,cols as ( select table_name ,cols ,access_predicates ,filter_predicates ,sum(cnt)over(partition by table_name,cols) total_by_cols ,cnt from agg ,xmltable( 'string-join(for $c in /ROWSET/ROW/COL order by $c return $c,",")' passing xmltype( cursor( (select distinct nvl( regexp_substr( access_predicates||' '||filter_predicates ,'("'||alias||'"\.|[^.]|^)"([A-Z0-9#_$]+)"([^.]|$)' ,1 ,level ,'i',2 ),' ') col from dual connect by level<=regexp_count( access_predicates||' '||filter_predicates ,'("'||alias||'"\.|[^.]|^)"([A-Z0-9#_$]+)"([^.]|$)' ) ) )) columns cols varchar2(400) path '.' )(+) order by total_by_cols desc, table_name, cnt desc ) select table_name ,cols ,sum(cnt)over(partition by table_name,cols) total_by_cols ,access_predicates ,filter_predicates ,cnt from cols where rownum<=50 order by total_by_cols desc, table_name, cnt desc; 

Seperti yang dapat Anda lihat dari kueri itu sendiri, ia menampilkan 50 kolom pencarian teratas dan predikatnya sendiri berdasarkan berapa kali ASH hit dalam 3 jam terakhir. Terlepas dari kenyataan bahwa ASH hanya menyimpan foto setiap detik, pengambilan sampel di pangkalan yang dimuat sangat representatif. Itu dapat mengklarifikasi beberapa poin:

  • Kolom cols - menampilkan kolom pencarian sendiri, dan total_by_cols - jumlah entri dalam konteks kolom ini.
  • Saya pikir cukup jelas bahwa informasi ini sendiri bukanlah penanda yang cukup dari masalah, karena misalnya, beberapa fullscans satu kali dapat dengan mudah merusak statistik, sehingga Anda harus mempertimbangkan sendiri kueri dan frekuensinya (v $ sqlstats, dba_hist_sqlstat)
  • Pengelompokan oleh OBJECT_ALIAS di dalam SQL_ID, plan_hash_value penting untuk menggabungkan predikat indeks dan tabel berdasarkan objek, karena saat mengakses tabel melalui indeks, predikat akan dibagi menjadi beberapa baris rencana:
    gambar

Bergantung pada kebutuhan, skrip ini dapat dengan mudah dimodifikasi untuk mengumpulkan informasi tambahan di bagian lain, misalnya, dengan mempertimbangkan partisi atau harapan. Dan setelah menganalisis informasi ini, ditambah dengan analisis statistik tabel dan indeksnya, skema data umum, dan logika bisnis, Anda dapat memberikan rekomendasi kepada pengembang atau arsitek untuk memilih solusi, misalnya: opsi untuk denasionalisasi atau mengubah skema atau indeks partisi.

Sering juga dilupakan untuk menganalisis lalu lintas net * SQL, dan ada juga banyak seluk-beluk, misalnya: ukuran-ambil, SQLNET.COMPRESI, tipe data yang diperluas, yang memungkinkan pengurangan jumlah perjalanan ulang, dll., Tetapi ini adalah topik untuk artikel yang terpisah.

Sebagai kesimpulan, saya ingin mengatakan bahwa sekarang pengguna menjadi kurang toleran terhadap penundaan, mengoptimalkan kinerja menjadi keunggulan kompetitif.

Source: https://habr.com/ru/post/id451676/


All Articles