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
(
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‘
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 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