建立函式索引優化一條SQL

2021-06-07 12:24:00 字數 3138 閱讀 6740

開發發來一條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

wheret_to_order_tickets.order_id = oi.order_id

andto_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工具中找不到topsql,自己如何分

析定位到這個點上面來。t_to_order_tickets這張表後面where欄位有等號的地方,就

是這種字段。這次調優沒有經驗,下次在看到如果在時間字段上面做了手段,就應該將

問題快速的定位到這個上面來

一條sql 語句的優化

第二個版本 一條sql搞定,使用巢狀查詢,費時2 3分鐘 select a.indexid,c.title,c.createdtime,c.intro,d.picurl,e.src,e.size,e.info from mms content index a,mms index node b,mms...

SQL優化之建立索引一

基於索引的sql語句優化之降龍十八掌 塵封往事 引用功能被關閉了。前言 客 服業務受到sql語句的影響非常大,在規模比較大的局點,往往因為乙個小的sql語句不夠優化,導致資料庫效能急劇下降,小型機idle所剩無幾,應用服 務器斷連 超時,嚴重影響業務的正常執行。因此,稱低效的sql語句為客服業務的 ...

優化一條UPDATE語句

最近見到一條開發人員寫的update語句,覺得沒什麼不對,可又覺得有地方不對,因為效能低下.update a set col2,col3 select col1,t from b where b.col1 a.col1 where exists select b.col1 from b where ...