官术网_书友最值得收藏!

icon1

第1章 與SQL優化相關的幾個案例

 

案例1 一條SQL引發的血案

1.案例說明

某大型電商公司數據倉庫系統,正常情況下每天凌晨0~9點會執行大量作業生成前一天的業務報表,供管理層分析使用。但某天早晨6點開始,監控人員就頻繁收到業務報警,大批業務報表突然出現大面積延遲。原本8點前就應跑出的報表,一直持續到10點仍然沒有結果。公司領導非常重視,嚴令在11點前必須解決問題。

DBA緊急介入處理,通過TOP命令查看到某個進程占用了大量資源,殺掉后不久還會再次出現。經跟開發人員溝通,這是由于調度機制所致,非正常結束的作業會反復執行。暫時設置該作業無效,并從腳本中排查可疑SQL。同時對比從線上收集的ASH/AWR報告,最終定位到某條SQL比較可疑,經跟開發人員確認系一新增功能,因上線緊急,只做了簡單的功能測試。正是因為這一條SQL,導致整個系統運行緩慢,大量作業受到影響,修改SQL后系統恢復正常。

具體分析:

SELECT /*+ INDEX A1 xxxxx */ SUMA2.CRKSL),  SUMA2.CRKSL*A2.DJ ...
FROM xxxx A2 xxxx A1
WHERE A2.CRKFLAG=xxx AND A2.CDATE>=xxx AND A2.CDATE<xxx

這是一個很典型的兩表關聯語句,兩張表的數據量都較大。下面來看看執行計劃,如圖1-1所示。

圖1-1 執行計劃

執行計劃觸目驚心,優化器評估返回的數據量為3505T條記錄,計劃返回量127P字節,總成本9890G,返回時間999:59:59。

分析結論:從執行計劃中可見,兩表關聯使用了笛卡兒積的關聯方式。我們知道笛卡兒連接是指在兩表連接沒有任何連接條件的情況。一般情況下應盡量避免笛卡兒積,除非某些特殊場合。否則再強大的數據庫,也無法處理。這是一個典型的多表關聯缺乏連接條件,導致笛卡兒積,引發性能問題的案例。

2.給我們的啟示

從案例本身來講,并沒有什么特別之處,不過是開發人員疏忽,導致了一條質量很差的SQL。但從更深層次來講,這個案例可以給我們帶來如下啟示:

  • 開發人員的一個疏忽,造成了嚴重的后果,原來數據庫竟是如此的脆弱。需要對數據庫保持一種“敬畏”之心。
  • 電腦不是人腦,它不知道你的需求是什么,只能根據寫好的邏輯進行處理。
  • 不要去責怪開發人員,誰都會犯錯誤,關鍵是如何從制度上保證不再發生類似的問題。
3.解決之道

(1)SQL開發規范

加強對數據庫開發人員的培訓工作,提高其對數據庫的理解能力和SQL開發水平。將部分SQL運行檢查的職責前置,在開發階段就能規避很多問題。要向開發人員灌輸SQL優化的思想,在工作中逐步積累,這樣才能提高公司整體開發質量,也可以避免很多低級錯誤。

(2)SQL Review制度

對于SQL Review,怎么強調都不過分。從業內來看,很多公司也都在自己的開發流程中納入了這個環節,甚至列為考評范圍,對其重視程度可見一斑。其常見典型做法是利用SQL分析引擎(商用或自研)進行分析或采取半人工的方式進行審核。對于審核后的結果,可作為持續改進的依據。SQL Review的中間結果可以保留,作為系統上線后的對比分析依據,進而可將SQL的審核、優化、管理等功能集成起來,完成對SQL整個生命周期的管理。

(3)限流/資源控制

有些數據庫提供了豐富的資源限制功能,可以從多個維度限制會話對資源(CPU、MEMORY、IO)的使用。可避免發生單個會話影響整個數據庫的運行狀態。對于一些開源數據庫,部分技術實力較強的公司,還通過對內核的修改實現了限流功能,控制資源消耗較多的SQL運行數量,從而避免拖慢數據庫的整體運行。

主站蜘蛛池模板: 胶南市| 德江县| 苍南县| 吴江市| 万山特区| 达拉特旗| 祁东县| 大荔县| 南澳县| 伊通| 太康县| 临安市| 崇礼县| 个旧市| 甘德县| 灵石县| 民县| 临邑县| 镇坪县| 临汾市| 扬州市| 天水市| 仙游县| 华蓥市| 长春市| 平安县| 昭苏县| 隆尧县| 林西县| 宝应县| 高邑县| 昌乐县| 图们市| 龙门县| 甘谷县| 于都县| 阳泉市| 遵义市| 无为县| 始兴县| 南宁市|