1. 程式人生 > >SQL優化-子查詢&case&limit

SQL優化-子查詢&case&limit

子查詢優化

load 導數據.notesdxtdb 數據庫 total_time 475.60秒。 監控服務:倉頡

技術分享select t_.*,
a.name acquirer_name,
m.merchant_name,
am.merchant_name acq_merchant_name,
ag.name agency_name

from
(
select t.* ,
c.cardbin_name,
c.issuer_name cardbin_issuer_name,
CASE c.card_type
WHEN ‘debit‘ THEN ‘XXX‘
WHEN ‘prepaid‘ THEN ‘XXX‘
WHEN ‘credit‘ THEN ‘XXX‘
WHEN ‘semiCredit‘ THEN ‘XXX‘
END ‘card_type‘
from trans_history t
join dict_cardbin c on t.cardbin_id = c.id
where 1=1 order by t.id desc ) t_
left join cm_merchant m on t_.merchant_id=m.id
left join acquirer a on t_.acquirer_id = a.id
left join acq_merchant am on t_.acq_merchant_id = am.id
left join agency ag on m.agency_id = ag.id
order by t_.id desc limit 0, 20;

表:
trans_history t
子查詢的 結果集是 t_
dict_cardbin c
cm_merchant m
acquirer a
acq_merchant am
agency ag

關聯:
c on t.cardbin_id = c.id
t_.merchant_id=m.id
t_.acquirer_id = a.id
t_.acq_merchant_id = am.id
m.agency_id = ag.id

子查詢結果集要:
c.cardbin_name,
c.issuer_name
cardbin_issuer_name,

外部結果要:
t_.*,

c.cardbin_name,
c.issuer_name
t.cardbin_issuer_name,
a.name acquirer_name,
m.merchant_name,
am.merchant_name
t.acq_merchant_name,
ag.name agency_name

以下SQL未經驗證,全憑個人經驗 對其SQL改寫。
(剛來新公司,還沒有權限登錄 跟查驗表結構 執行計劃。)
目測 第一步設計的6個表的left join 以及判斷
第二步 如這個查詢業務功能上來說 屬於頻繁性的,需要設計視圖方式解決。
視圖采用 CASCADED 方式。

查詢需要:
trans_history t 全字段數據; 其他表 都個需要某幾個字段數據。

select t.*,c.cardbin_name,c.issuer_name,t.cardbin_issuer_name,a.name acquirer_name,m.merchant_name,am.merchant_name,t.agency_name from ((((trans_history t join dict_cardbin c on t.cardbin_id = c.id ) left join cm_merchant m on t.merchant_id=m.id) left join acquirer a on t.acquirer_id = a.id ) left join acq_merchant am on t.acq_merchant_id = am.id ) left join agency ag on m.agency_id = ag.id order by t.id desc limit 0, 20;

card_type 列要做運算。這裏 應該存 enum 0;1;2;3 這樣的字段,邏輯端拿到數值,前端做渲染。 否則 這個CASE 沒辦法在第一個版本當中優化掉。
card_type 字段,我這裏就簡寫了。沒有加入case 判斷。


select t.*,c.cardbin_name,c.issuer_name,a.name,acquirer_name,m.merchant_name,am.merchant_name,t.agency_name from ((((trans_history t join dict_cardbin c on t.cardbin_id = c.id ) left join cm_merchant m on t.merchant_id=m.id) left join acquirer a on t.acquirer_id = a.id ) left join acq_merchant am on t.acq_merchant_id = am.id ) left join agency ag on m.agency_id = ag.id order by t.id desc limit 0, 20;


select t.*,c.cardbin_name,c.issuer_name,t.cardbin_issuer_name,c.card_type,a.name acquirer_name,m.merchant_name,am.merchant_name,t.agency_name from ((((trans_history t join dict_cardbin c on t.cardbin_id = c.id ) left join cm_merchant m on t_.merchant_id=m.id) left join acquirer a on t_.acquirer_id = a.id ) left join acq_merchant am on t_.acq_merchant_id = am.id ) left join agency ag on m.agency_id = ag.id order by t.id desc where id >0 limit 20;

視圖方式:
LOCAL只要滿足本視圖的條件就可以更新;
CASCADED則必須滿足所有針對該視圖的所有視圖的條件才可以更新

create view card as select t.*,c.cardbin_name,c.issuer_name,t.cardbin_issuer_name,a.name acquirer_name,m.merchant_name,am.merchant_name,t.agency_name from ((((trans_history t join dict_cardbin c on t.cardbin_id = c.id ) left join cm_merchant m on t_.merchant_id=m.id) left join acquirer a on t_.acquirer_id = a.id ) left join acq_merchant am on t_.acq_merchant_id = am.id ) left join agency ag on m.agency_id = ag.id with local check option;


解決哪些問題:
1 解決了 表結構類型的問題。使用了enum 並利用前端做判斷展示出來。
2 解決了子查詢 用left join方式替換。
3 解決了limit 查詢效率差的問題,用where 解決。


本文出自 “晴空” 博客,謝絕轉載!

SQL優化-子查詢&case&limit