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