一條update語句的優化探索
今天經開發同學反饋,發現有一些update語句阻塞了部分業務流程,為什麼說一些而不是一條,是因為這些update語句都在一個儲存過程中,語句結構相仿,真有一種一榮俱榮,一損俱損的感覺。而比較糾結的是這樣的update語句有差不多10個。從我收到反饋到觀察分析,裡面的第一條update語句執行了近5個小時,還沒有完成,從SQL Monitor的報告來看,似乎進度甚微,按照這個進度,這些語句的執行時間會非常驚人。
我先拿到了一個初步的報告。
概覽資訊如下:
這條語句從生成的執行計劃來看,簡直完美,但是執行時間卻差強人意,所以由此來看是執行計劃出現了巨大的偏差。這個時候SQL Monitor是一個利器,可以真實還原問題時段的執行計劃情況。
如果看上面的執行計劃,其實看起來消耗也不大,好像都走了索引,在這樣的一個評估值的情況下,可見資料集的變化不大。而問題就在於右邊的部分。
紅色的小框處標出的資訊,可以看出實際得到的結果集非常驚人,結果集行數都是4G,這是一個什麼級別的概念。所以這個語句的瓶頸就在這個地方。
我們來看看語句:
這個語句看起來還是比較複雜的,兩個相關的表都是千萬級別,紅色的部分就是涉及的關鍵部分,都涉及到vip_recharge_log這張大表。從執行計劃來看是在這裡出了問題。
vip_recharge_log對應的索引資訊如下:
可以看出這個語句是根據時間欄位來做的資料過濾。這種方式為什麼效能低效呢,和between的部分有著重大的關係。
時間跨度有多大呢,可以通過如下的表示式來得到一個時間範圍。
這是取近半年的資料結果,對於一個OLTP的千萬級表來說,全表掃描的代價其實要更低一些。這樣SQL在執行的過程中先根據時間欄位來過濾得到一個極大的結果集,然後在這個基礎上去根據id得到一個極小的結果集。這種方式簡直是百害而無一利。如果根據id得到一些客戶的資訊,因為本身結果集就小很多,在這個基礎上再根據時間來過濾,那效率會大大提高,在目前的這個場景中可以看見明顯的效能問題。
所以初步的評估就是重構索引。目前的索引是根據時間欄位或者根據id來建立索引,其實可以考慮複合索引,根據id,時間欄位來過濾資料,成本相對要低很多。所以考慮建立一個新的索引
CREATE INDEX "IDX_VIP_RECHARGE_MIX" ON "VIP_RECHARGE_LOG"
(CN,CHARGE_DATE ) ;
這樣資料過濾的效果就會好很多。這個瓶頸能夠化解了,其它的幾個問題也就引刃而解。
所以在這種場景下,不修改SQL語句,調整索引就預估達到極大的效能提升。而對於此還是需要很謹慎的,我複製了表中的資料,在另外的環境進行了快速的復現,執行計劃的效率大大提高。在這個基礎上,考慮新增了並行,雖然會消耗伺服器的資源,但是能夠極大提高效率,這些付出也是合理的。在這些簡單調整之後,再次測試執行語句,1分半鐘就能夠順利完成。來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-2122951/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20181114]一條sql語句的優化.txtSQL優化
- 一條update SQL語句是如何執行的SQL
- 優化 JS 條件語句的 5 個技巧優化JS
- 一個UPDATE語句引發的血案
- Mysql 52條SQL語句效能優化策略彙總MySql優化
- MySQL的update語句避坑MySql
- SQL語句優化SQL優化
- 一條update語句到底加了多少鎖?帶你深入理解底層原理
- 【SQL】10 SQL UPDATE 語句SQL
- MySQL——優化ORDER BY語句MySql優化
- MYSQL SQL語句優化MySql優化
- sql語句效能優化SQL優化
- 優化 SQL 語句的步驟優化SQL
- 一條更新語句的執行流程
- MySQL -update語句流程總結MySql
- ORACLE多表關聯UPDATE語句Oracle
- 比CRUD多一點兒(三):UPDATE、DELETE語句delete
- MySQL之SQL語句優化MySql優化
- [20201210]sql語句優化.txtSQL優化
- [20200320]SQL語句優化的困惑.txtSQL優化
- MySQL系列6 - join語句的優化MySql優化
- 條件語句
- 第45期:一條 SQL 語句最佳化的基本思路SQL
- 一條查詢語句的執行流程
- 一條sql語句的執行過程SQL
- Oracle優化案例-單表分頁語句的優化(八)Oracle優化
- SQL優化案例-單表分頁語句的優化(八)SQL優化
- SQLite語句(二):INSERT DELETE UPDATE SELECTSQLitedelete
- 用一條mysql語句插入多條資料MySql
- 根據某個查詢條件的前50條資料來決定UPDATE語句的更新範圍
- oracle中的條件語句Oracle
- MySQL 中 一條 order by index limit 語句的分析MySqlIndexMIT
- MySQL 匯出一條資料的插入語句MySql
- 一條SQL更新語句是如何執行的SQL
- 一條SQL更新語句是如何執行的?SQL
- MySQL:一條更新語句是如何執行的MySql
- javaScript條件語句JavaScript
- GO 條件語句Go
- 一條更新的SQL語句是如何執行的?SQL