2016-09-22 7 views
0

私は読みにくいクエリを書いていましたが、効率が悪いかもしれません。このクエリは、各テーブルからconsumerdata.consumeridに一致するコンシューマIDの面でより効率的に記述できますか?左結合 - より効率的にするにはどうすればいいですか?

select 

consumerdata.consumerid, 
signupdate, 
city, 
state, 
year(DOB), 
topaffiliate, 
activestatus, 
lastuseddate, 

(select sum(achload.transactionamount) from achload where achload.consumerid = consumerdata.consumerid) as Total_ACH, 
(select sum(billpay.transactionamount) from billpay where billpay.consumerid = consumerdata.consumerid) as Bill_Pay, 
(select sum(recharge.transactionamount) from recharge where recharge.consumerid = consumerdata.consumerid) as Revenue, 
(select count(cash.consumerid) from Cash where cash.consumerid = consumerdata.consumerid) as Cash__TXNs, 
(select sum(moneytransfer.transactionamount) from moneytransfer where moneytransfer.consumerid = consumerdata.consumerid) as Transfer, 
(select sum(moneytransfer.commissionfeeamount) from moneytransfer where moneytransfer.consumerid = tbl_accounts_consumerdata.consumerid) as commission_fee, 
(select count(interchangetransactions.transactiondescription) from interchangetransactions where interchangetransactions.transactiondescription = "Withdrawal" and interchangetransactions.consumerid = consumerdata.consumerid) as Withdrawals, 
(select count(interchangetransactions.responsecode) from interchangetransactions where interchangetransactions.responsecode in (01) and interchangetransactions.consumerid = consumerdata.consumerid and interchangetransactions.transactiondescription = "Withdrawal") as Code_01, 
(select count(interchangetransactions.responsecode) from interchangetransactions where interchangetransactions.responsecode in (02) and interchangetransactions.consumerid = consumerdata.consumerid and interchangetransactions.transactiondescription = "Withdrawal") as Code_02, 
(select count(interchangetransactions.transactiondescription) from interchangetransactions where interchangetransactions.transactiondescription IN ("2 Cash Advance", "1 Cash Advance") and interchangetransactions.consumerid = consumerdata.consumerid) as Cash_Advance_Count, 
(select count(interchangetransactions.transactiondescription) from interchangetransactions where interchangetransactions.transactiondescription IN ("Balance") and interchangetransactions.consumerid = consumerdata.consumerid) as Inquiry_Count, 
(select sum(interchangetransactions.transactionamount) from interchangetransactions where interchangetransactions.transactiontypecode = 195 and interchangetransactions.consumerid = consumerdata.consumerid) as Intnl_TXN_Sum, 
(select count(interchangetransactions.transactionamount) from interchangetransactions where interchangetransactions.transactiontypecode = 195 and interchangetransactions.consumerid = consumerdata.consumerid) as Intnl_TXN_Count 


from 
consumerdata 

left join achload 
on achload.consumerid=consumerdata.consumerid 

left join billpay 
on billpay.consumerid = consumerdata.consumerid 

left join recharge 
on recharge.consumerid = consumerdata.consumerid 

left join cash 
on cash.consumerid = consumerdata.consumerid 

left join moneytransfer 
on moneytransfer.consumerid = consumerdata.consumerid 

left join interchangetransactions 
on interchangetransactions.consumerid = consumerdata.consumerid 

where consumerdata.signupdate between date(20120101) and curdate() 
group by consumerdata.consumerid order by signupdate asc; 
+0

サブクエリでもクエリしている同じテーブルに対して、「LEFT JOIN」があるのは変です。両方をしてはいけません。 – Barmar

+1

他の 'SELECT'カラムはどのテーブルから来ますか? – Barmar

+0

先頭のselect文は、すべてconsumerdataテーブルからのものです。あなたが都市、州、年(dob)を参照している場合。 –

答えて

1

トランザクションテーブルのいずれかから何かを選択していないので、簡単な改善はすべてLEFT JOIN句を取り除くことであろう。相関サブクエリから合計を取得しているため、何も使用されていません。これは、データベースがすべてのテーブルの間に巨大なクロスプロダクトを作成する原因となり、次にGROUP BYを実行すると破棄されます。

これを実行するもう1つの方法は、相関サブクエリではなく、各トランザクションテーブルのグループ化された合計を計算するサブクエリで結合することです。

select 
    c.consumerid, signupdate, state, year(DOB), topaffiliate, activestatus, lastuseddate, 
    IFNULL(Total_ACH, 0) AS Total_ACH, IFNULL(Bill_Pay, 0) AS Bill_Pay, IFNULL(Revenue, 0) AS Revenue, 
    IFNULL(Cash__TXNs, 0) AS Cash__TXNs, ... 
FROM consumerdata AS c 
LEFT JOIN (
    SELECT consumerid, SUM(transactionamount) AS Total_ACH 
    FROM achload 
    GROUP BY consumerid) AS a ON a.consumerid = c.consumerid 
LEFT JOIN (
    SELECT consumerid, SUM(transactionamount) AS Bill_Pay 
    FROM billpay 
    GROUP BY consumerid) AS b ON b.consumerid = c.consumerid 
LEFT JOIN (
    SELECT consumerid, SUM(transactionamount) AS Revenue 
    FROM recharge 
    GROUP BY consumerid) AS r ON r.consumerid = c.consumerid 
LEFT JOIN (
    SELECT consumerid, COUNT(*) AS Cash__TXNs 
    FROM Cash 
    GROUP BY consumerid) AS cash ON cash.consumerid = c.consumerid 
... 
WHERE c.signupdate between DATE(20120101) and CURDATE() 
ORDER BY signupdate ASC 

私は実際に速くなりますどの方法かわからない - それはおそらくサインアップの日付が指定範囲外にある消費者のためのトランザクションテーブルであり、どのくらいのデータに依存するであろう。両方を試し、どちらが良いかを見てください。

+0

あなたの助けを借りてくれてありがとうBarmar。あなたの答えを見た後、私は左の結合をどのように利用するかをもっとよく理解しています。 –

関連する問題