SQL優化--函式索引
select distinct oi.customer_id, oi.order_id, oi.create_time, 1 type from t_to_order_info oi left join t_TO_Consign_Pymt_Record cpr on oi.order_id = cpr.order_id where 1 = 1 and exists (select 1 from t_TO_Order_Tickets where t_TO_Order_Tickets.Order_ID = oi.Order_ID and to_char(Departure_Time, 'yyyyMMdd') = to_char(sysdate, 'yyyyMMdd')) and not exists (select 1 from t_to_order_change oc where oc.order_id = oi.order_id) and ((cpr.pymt_type = 1 or cpr.pymt_type = 3 and oi.guest_pymt_sts_id = 2) or (cpr.pymt_type = 2 and cpr.partner_id in (select p.partner_id from t_tp_partner p where p.is_company_inner = 1) and oi.guest_pymt_sts_id = 2) or (cpr.pymt_type = 2 and cpr.partner_id in (select p.partner_id from t_tp_partner p where p.agent_class_id = 1 and p.is_company_inner != 1) and to_char(oi.issue_time) <> ' ') or (cpr.pymt_type = 2 and cpr.partner_id in (select p.partner_id from t_tp_partner p where p.agent_class_id != 1) and to_char(oi.issue_time) <> ' '))
這麼一條SQL,要跑30多秒,開發讓調優
我第一的想法是看執行計劃,t_to_order_info和t_TO_Order_Tickets這兩張表是hash連線,但是兩表走的是全表掃描,我首先是將目標定向了t_to_order_info走全表掃描的原因,以為是exists造成的, 在這裡我並不知道是哪裡沒走索引造成的,我將SQL多執行了幾次,然後再em工具裡面的TOP SQL裡面找到了這條SQL,看了oracle給的建議
首先執行了如下命令收集了索引的統計資訊
dbms_stats.gather_index_stats(ownname => 'TEST20110217', indname => 'IDX_BT_T_TO_ORDER_HANG', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE);
dbms_stats.gather_index_stats(ownname => 'TEST20110217', indname => 'TO_RELATIONCHANGE_FK', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE);
dbms_stats.gather_index_stats(ownname => 'TEST20110217', indname => 'PK_T_TO_ORDER_CHANGE', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE);
end;
做完次操作後效率沒有提高,再看到oracle給的一個建議,就是說
t_TO_Order_Tickets
where t_TO_Order_Tickets.Order_ID = oi.Order_ID
and to_char(Departure_Time, 'yyyyMMdd') =
to_char(sysdate, 'yyyyMMdd'))
這裡出了問題,Departure_Time本來是有索引的,但是這裡沒有走索引,因為to_char的方式無法讓它再走索引了,這是問題的關鍵,這種問題可以通過函式索引來解決
SQL> create index TEST20110217.IDX_HANSU on TEST20110217.T_TO_ORDER_TICKETS(TO_CHAR("DEPARTURE_TIME",'yyyyMMdd'));
SQL> exec dbms_stats.gather_index_stats('TEST20110217','IDX_HANSU');
上面建立了函式索引變收集了新索引的統計資訊,SQL的效率得到了大大的提高,差不多1秒之類就OK了,同時驗證了一點就是一個列上函式索引和普通索引可以並存他們各走各的,不影響效能,問題本來在這裡就已經解決了了,但是開發的後面需要在 DEPARTURE_TIME+1這將再次引起不走索引的情況,那麼必須通過改寫SQL的方式來解決
and Departure_Time between to_date( to_char(sysdate-1,'YYYY-MM-DD HH24:MI:SS') ,'YYYY-MM-DD HH24:MI:SS')
and to_date( to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') ,'YYYY-MM-DD HH24:MI:SS'))
其實問題的關鍵就在departure_time,用上面這種方式不變departure_time,改變等號的那邊方可解決走索引的問題。
總結:
整個問題的關鍵地方是如何定位到問題是departure_time列不走索引而引起的效能問題,
這次是通過em工具找出來的提醒,那麼如果下次在em工具中找不到TOP SQL,自己如何分
析定位到這個點上面來。t_TO_Order_Tickets 這張表後面where 欄位有等號的地方,就
是這種欄位。這次調優沒有經驗,下次在看到如果在時間欄位上面做了手段,就應該將
問題快速的定位到這個上面來
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10678398/viewspace-715093/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL優化案例-自定義函式索引(五)SQL優化函式索引
- 高效的SQL(函式索引優化VIEW一例)SQL函式索引優化View
- MySQL函式索引及優化MySql函式索引優化
- SQL優化中索引列使用函式之靈異事件SQL優化索引函式事件
- SQL優化-索引SQL優化索引
- 複合索引與函式索引優化一例索引函式優化
- Oracle優化案例-自定義函式索引(五)Oracle優化函式索引
- SQL最佳化案例-自定義函式索引(五)SQL函式索引
- 聊聊索引和SQL優化索引SQL優化
- 函式索引使用細節——自定義函式的索引化函式索引
- SQL優化之利用索引排序SQL優化索引排序
- SQL Server 聚合函式演算法優化技巧SQLServer函式演算法優化
- sql優化案例一:使用了表示式不會使用索引SQL優化索引
- sql優化用group by 函式代替分析函式SQL優化函式
- SQL最佳化中索引列使用函式之靈異事件SQL索引函式事件
- Excel 優化函式Excel優化函式
- MySQL SQL 優化之覆蓋索引MySql優化索引
- sql優化之多列索引的使用SQL優化索引
- 資料庫效能優化-索引與sql相關優化資料庫優化索引SQL
- SQL優化案例-分割槽索引之無字首索引(六)SQL優化索引
- SQL優化之統計資訊和索引SQL優化索引
- SQL優化(二)(聯合索引的使用)SQL優化索引
- SQL優化思路&結果集重用優化、分割槽索引優化測試SQL優化索引
- SQL優化] 避免在WHERE子句中對列使用函式SQL優化函式
- 《MySQL慢查詢優化》之SQL語句及索引優化MySql優化索引
- SQL精華總結索引型別優化SQL優化事務大表優化思維導圖❤️SQL索引型別優化
- SQL Server索引優化系列之二:索引效能考慮 (轉)SQLServer索引優化
- Oracle優化-索引原理[注意索引跳躍式掃描!Oracle優化索引
- 理解索引:索引優化索引優化
- SQL優化案例-正確的使用索引(二)SQL優化索引
- MS SQL SERVER索引優化相關查詢SQLServer索引優化
- MySQL SQL優化 - 覆蓋索引(covering index)MySql優化索引Index
- [zt] 基於索引的SQL語句優化索引SQL優化
- mysql優化 | 儲存引擎,建表,索引,sql的優化建議MySql優化儲存引擎索引
- 記錄一次SQL函式和優化的問題SQL函式優化
- 高效的SQL(Function-based Indexes 函式、運算優化思路)SQLFunctionIndex函式優化
- React函式式元件的效能優化React函式元件優化
- 函式索引陷阱函式索引