作者介紹: 曾令軍,云和恩墨技術(shù)專家,,2009年開始接觸ORACLE數(shù)據(jù)庫,,8年數(shù)據(jù)庫運(yùn)維經(jīng)驗(yàn)。思維敏捷,,擅長于數(shù)據(jù)庫開發(fā),、解決棘手的數(shù)據(jù)庫故障和性能問題。服務(wù)于公司華南區(qū)多個客戶,,曾參與過國內(nèi)多家股份制銀行,、城市商業(yè)銀行的核心業(yè)務(wù)系統(tǒng)、數(shù)據(jù)倉庫的部署建設(shè)和生產(chǎn)運(yùn)維工作,,在數(shù)據(jù)庫故障診斷,、運(yùn)維監(jiān)控、性能優(yōu)化方面積累了豐富的經(jīng)驗(yàn),。 問題現(xiàn)象 客戶反饋核心業(yè)務(wù)系統(tǒng)中,,出現(xiàn)多條Sql執(zhí)行效率很低,執(zhí)行計(jì)劃走了錯誤的索引,,原因是統(tǒng)計(jì)信息不對,,經(jīng)過統(tǒng)計(jì)信息收集并顯示授權(quán)后(相當(dāng)于收集統(tǒng)計(jì)信息時設(shè)置了noinvalidation=false選項(xiàng),共享池中原有的游標(biāo)會失效),,執(zhí)行計(jì)劃并沒有及時改變,。一段時間后又恢復(fù)正常。 令人疑惑的問題點(diǎn): 1)為什么收集完統(tǒng)計(jì)信息并對SQL查詢的表顯示授權(quán)后,,執(zhí)行計(jì)劃并沒有馬上改變 2)為什么每天定時收集統(tǒng)計(jì)信息的任務(wù)沒有起作用 問題分析 1. 根據(jù)客戶提供的sql_id,,分析該sql_id的執(zhí)行計(jì)劃,走錯了索引,。 h_kns_tran_fund表有1億+紀(jì)錄數(shù),,sql條件中字段明顯應(yīng)該走pk_h_kns_tran_fund索引,但CBO優(yōu)化器卻選擇了idx_h_kns_tran_fund_acctno這個索引,,這樣會導(dǎo)致分區(qū)全掃描,。通常這種情況都是統(tǒng)計(jì)信息不對引起,檢查統(tǒng)計(jì)信息,,確實(shí)有問題,。于是手工收集,但是過了一個小時左右,,執(zhí)行計(jì)劃才恢復(fù)正常,。 針對這個問題: 檢查業(yè)務(wù)程序,發(fā)現(xiàn)程序中存在一個if else判斷,,如果傳入的日期為當(dāng)天,,就不會查h_kns_tran_fund這個表,,如果是歷史日期才查。通過這條線索,,檢查dba_hist_sql_bind_capture視圖,,發(fā)現(xiàn)該sql執(zhí)行頻率很低,隔一兩個小時才有一次,,因此執(zhí)行計(jì)劃沒有改變的原因,可以斷定就是SQL在原有的執(zhí)行計(jì)劃失效后,,一直都沒有符合輸入歷史查詢條件的SQL執(zhí)行過,,沒有發(fā)生新的SQL解析,產(chǎn)生新的正確的執(zhí)行計(jì)劃,。 2. 為什么系統(tǒng)開啟了每天的自動收集統(tǒng)計(jì)信息任務(wù),,該表卻沒有收集到統(tǒng)計(jì)信息呢? 檢查表結(jié)構(gòu),,發(fā)現(xiàn)這是一個分區(qū)表,,每天一個分區(qū)(例如p20160428),與開發(fā)人員確認(rèn),,當(dāng)天的業(yè)務(wù)數(shù)據(jù)是記錄在kns_tran_fund表中,,這些數(shù)據(jù)每天晚上由業(yè)務(wù)程序插入到歷史表h_kns_tran_fund的pever分區(qū)中,插完數(shù)據(jù)之后再將pever進(jìn)行拆分,,split出一個上日的分區(qū)(例如p20160429和pever),,這就是說p20160429在當(dāng)天被split出來之后,數(shù)據(jù)就不會再發(fā)生變化,。 oracle 10g 統(tǒng)計(jì)信息自動收集的原則,,是看數(shù)據(jù)量變更是否超過了10% ,這個變化量可以在dba_tab_modifications視圖中查到,,如果達(dá)到這個閥值,,收集統(tǒng)計(jì)信息的定時任務(wù)運(yùn)行時就會收集這個表的統(tǒng)計(jì)信息。 例如: 插入10萬條記錄到pever分區(qū),,手工執(zhí)行dbms_stats. flush_database_monitoring_info (),,dba_tab_modifications視圖中就會多出一條pever分區(qū)的紀(jì)錄,插入次數(shù)為10萬,。 這個案例的問題在于: 數(shù)據(jù)插入到歷史表,,然后再split出一個p20160429分區(qū),p20160429這個分區(qū)雖然此時有10萬條紀(jì)錄,,但數(shù)據(jù)不再變化,,所以dba_tab_modifications視圖中不會有這個新分區(qū)的變化記錄,統(tǒng)計(jì)信息收集時并不會收集這個分區(qū),。 基于以上推測,來做一個實(shí)驗(yàn)進(jìn)行驗(yàn)證: 正常插入分區(qū)數(shù)據(jù),,用于對比 --此時可以看到dba_tab_modifications中紀(jì)錄了表和分區(qū)0502的變化情況,。 --檢查一次分區(qū)的統(tǒng)計(jì)信息,還沒有更新
--執(zhí)行一次自動統(tǒng)計(jì)信息收集的program_action,,分區(qū)0502的統(tǒng)計(jì)信息更新了,。
結(jié)論: 正常的數(shù)據(jù)插入操作,數(shù)據(jù)變化量達(dá)到收集統(tǒng)計(jì)信息的比例,,自動任務(wù)能夠收集 插入數(shù)據(jù)到最大分區(qū),,然后split出新分區(qū),觀察新分區(qū)的統(tǒng)計(jì)信息收集情況 --這里看到dba_tab_modifications中只紀(jì)錄了表和分區(qū)PEVER的變化情況,,卻沒有分區(qū)0503的紀(jì)錄 --先檢查一次分區(qū)的統(tǒng)計(jì)信息,,這里分區(qū)0503當(dāng)前是空值
--執(zhí)行一次自動統(tǒng)計(jì)信息收集的program_action,分區(qū)0503的統(tǒng)計(jì)信息也更新了,。
結(jié)論: dba_tab_modifications視圖中沒有新分區(qū)的變化紀(jì)錄,,但統(tǒng)計(jì)信息仍然更新了,原因是新分區(qū)此時的統(tǒng)計(jì)信息為空,,自動收集時會將這類對象一并收集,。不經(jīng)意間,又發(fā)現(xiàn)了一個知識點(diǎn),。 再次插入數(shù)據(jù)到最大分區(qū),,然后split出新分區(qū) --再執(zhí)行一次,情況發(fā)生了變化 --注意此時分區(qū)0504被split出來之后,,統(tǒng)計(jì)信息并不是空的,,而是0 --執(zhí)行一次自動統(tǒng)計(jì)信息收集的program_action,分區(qū)0504的統(tǒng)計(jì)信息并沒有更新
但實(shí)際上這個分區(qū)的紀(jì)錄數(shù)是1萬行,。 --隨后又做了幾次插入,、拆分、收集,,發(fā)現(xiàn)后面插入的數(shù)據(jù),,分區(qū)統(tǒng)計(jì)信息都是0,沒有再更新: 結(jié)論: dba_tab_modifications視圖中沒有新分區(qū)的變化紀(jì)錄,,且新分區(qū)的統(tǒng)計(jì)信息是0,,自動收集時并不收集這個新分區(qū)的統(tǒng)計(jì)信息。 這里引出了一個新的問題:為什么分區(qū)初始的統(tǒng)計(jì)信息,,第一次split分區(qū)后,,分區(qū)初始的統(tǒng)計(jì)信息是空,,而之后的split分區(qū)操作新分區(qū)的統(tǒng)計(jì)信息卻是0呢?通過反復(fù)實(shí)驗(yàn),、仔細(xì)對比觀察,,原來是split產(chǎn)生的新分區(qū)的初始統(tǒng)計(jì)信息繼承了split操作的源分區(qū)的統(tǒng)計(jì)信息。例如,,如果從pever這個分區(qū)上split出兩個分區(qū)P1和P2,,那么P1和P2的統(tǒng)計(jì)信息都與pever相同,pever的行數(shù)是空,,新分區(qū)也是空,,pever的行數(shù)是0,新分區(qū)也是0,,比較隱秘的設(shè)計(jì)。 說了這么多,,是時候總結(jié)一下啦,。通過這個案例我們學(xué)到了什么: SQL優(yōu)化時,如果能夠分析和理解業(yè)務(wù)程序的邏輯,,往往事半功倍 表或分區(qū)有超過10%的數(shù)據(jù)變化,,且被數(shù)據(jù)庫記錄到,自動收集任務(wù)才會更新這些對象的統(tǒng)計(jì)信息 對象的統(tǒng)計(jì)信息為空時,,自動收集任務(wù)會更新這些對象 Split分區(qū)操作時,,新分區(qū)即使有大量的數(shù)據(jù),統(tǒng)計(jì)信息也可能不會更新 Split分區(qū)操作時,,新分區(qū)的初始統(tǒng)計(jì)信息繼承于源分區(qū) 加入"云和恩墨大講堂",,參與討論學(xué)習(xí) |
|