當呼叫帶有以下查詢的Api時,我得到了 "操作在160000毫秒后超時,沒有收到任何位元組"。表包含大量的資料,所以我設定了限制,使其每次呼叫只獲取2000條記錄。但執行以下查詢仍然需要大量時間。
在我的PHP端,我添加了set_time_limit(0),增加了Curl請求的CURLOPT_TIMEOUT時間,洗掉了嵌套的for和foreach,但仍然無法作業。
我的MySQL查詢代碼喜歡如下所示。請幫助我優化該查詢。提前感謝
SELECT
sql_calc_found_rows
tm.TXNID,
tm.MERCHANT,
tm.AMOUNT。
tm.MERCHANT_TXN_DATE_TIME,
tm.TXN_TYPE。
CONCAT(PG_COMPANY,'-',cm.CHANNEL) AS BANK。
FROM[/span
tbl_master AS tm JOIN tbl_pg_rates AS c
ON c.mercant_channel_pg_id=tm.mercant_channel_pg_id
INNER JOIN tbl_pg_master AS cpm
ON c.channel_pg_id=cpm.channel_pg_id
INNER JOIN tbl_channel_master AS cm
ON cpm.CHANNELID=cm.CHANNELID
INNER JOIN tbl_payment_gateway_master AS pgm
ON cpm.PGID=pgm.PGID
WHERE
MERCHANT_TXN_DATE_TIME>=UNIX_TIMESTAMP('2021-09-01 00:00:00')
AND MERCHANT_TXN_DATE_TIME<=UNIX_TIMESTAMP('2021-09-16 23:59:59')
AND txn IN('netbnk', 'pg', 'ppc', 'upi')
and tm.PROFILEID=28688 and TXN_STATUS=1
AND txnid NOT IN(
SELECT tm.txnid
FROM `tbl_master` tm JOIN `tbl_irctc_refund_settled_txns` iref
ON tm.txnid = iref.txnid
WHERE[/span
CANCELLATION_DATE>='2021-09-01'/span>
AND CANCELLATION_DATE<='2021-09-16'
AND txn IN('netbnk', 'pg', 'pc', 'upi')
)
LIMIT 0,2000。
EXPLAIN的結果
。 id select_type table partitions type possible_keys key key_len ref rows filtersed Extra
------ ----------- ------ ---------- ------------------------------------------------------------------------------------- -------------- ------- ---------------------------------- ------ -------- -------------
1 PRIMARY tm (NULL) ref fk_TRANSACTION_MERCHANT_CHANNEL_PG_ID, PROFILEID,inx_txn_status,MERCHANT_TXN_DATE_TIME inx_txn_status 4 const 119 12。 50 使用 where
1 PRIMARY c (NULL) eq_ref PRIMARY, fk_RATES_CHANNELPGID PRIMARY 4 dbpayment. tm.MERCHANT_CHANNEL_PG_ID 1 100.00 (NULL)
1 PRIMARY cpm (NULL) eq_ref PRIMARY, fk_CHANNEL_ID,fk_PG_ID PRIMARY 4 dbpayment. c.CHANNEL_PG_ID 1 100.00 (NULL)
1 PRIMARY cm (NULL) eq_ref PRIMARY PRIMARY 4 dbpayment. cpm.CHANNELID 1 100.00 (NULL)
1 PRIMARY pgm (NULL) eq_ref PRIMARY PRIMARY 4 dbpayment. cpm.PGID 1 100.00 (NULL)
2 SUBQUERY iref (NULL) ALL (NULL) (NULL)(NULL)(NULL) 27 5。 55 使用 where
2 SUBQUERY tm (NULL) eq_ref PRIMARY, inx_txnid
uj5u.com熱心網友回復:
我同意這個意見。NOT IN SELECT會扼殺性能。 我會嘗試用tbl_irctc_refund_settled_txns進行左鍵連接,并在WHERE中增加條件。在類似的情況下進行了嘗試,對我來說是有效的:
SELECT
sql_calc_found_rows
tm.TXNID,
tm.MERCHANT,
tm.AMOUNT。
tm.MERCHANT_TXN_DATE_TIME,
tm.TXN_TYPE。
CONCAT(PG_COMPANY,'-',cm.CHANNEL) AS BANK
FROM銀行
tbl_master AS tm JOIN tbl_pg_rates AS c
ON c.merchant_channel_pg_id=tm.merchant_channel_pg_id
INNER JOIN tbl_pg_master AS cpm
ON c.channel_pg_id=cpm.channel_pg_id
INNER JOIN tbl_channel_master AS cm
ON cpm.CHANNELID=cm.CHANNELID
INNER JOIN tbl_payment_gateway_master AS pgm
ON cpm.PGID=pgm.PGID
LEFT JOIN `tbl_irctc_refund_settled_txns` iref
ON tm.txnid = iref.txnid
WHERE
MERCHANT_TXN_DATE_TIME>=UNIX_TIMESTAMP('2021-09-01 00:00:00')
and MERCHANT_TXN_DATE_TIME<=UNIX_TIMESTAMP('2021-09-16 23:59:59')
and txn in('netbnk', 'pg','ppc','upi')
and tm. PROFILEID=28688 AND TXN_STATUS=1
AND (iref.txnid IS NULL)
OR iref.CANCELLATION_DATE </span> '2021-09-01'
OR iref.CANCELLATION_DATE >/span> '2021-09-16')
LIMIT 0,2000。
uj5u.com熱心網友回復:
(假設某些列在tm中...)
iref: INDEX(txnid, txn, CANCELLATION_DATE)
tm: INDEX(PROFILEID, TXN_STATUS, txn, MERCHANT_TXN_DATE_TIME)
cpm。INDEX(channel_pg_id, PGID, CHANNELID)
cm: INDEX(CHANNELID, CHANNEL)
c: INDEX( merchant_channel_pg_id, channel_pg_id)
請提供EXPLAIN SELECT ...
uj5u.com熱心網友回復:
我認為很多人提出的建議都輕輕地跳過了子選擇中的一個重要專案。 你正在查詢整個Tbl_master,尋找2021-09-01和2021-09-16之間的cancellation_date,以及txn。 因此,如果你有數以百萬計的行,你就會被這個問題所困擾。 這可能有助于澄清和樣本資料,但資料查詢可能建議Merchant_txn_date_time將始終在交易中提供,而cancellation_date將是有條件的,只有當它代表一個針對先前交易的交易。
這就是說,你永遠不會有一個在原始交易之前的取消交易。 你的主查詢正在尋找發生在9/1和9/16之間的交易,我想補充的是,商人_txn_date_time也是你的子查詢的一部分,但只是為了限定FROM Date。 基本上限制了我想要所有在9/1日/之后發生的取消的交易。 而不是整個資料庫中的交易取消。
有交易的樣本資料來審查可能會有幫助,下面只是一個資料的猜測,對你自己將來提供類似的澄清有好處。
txnid Merchant_txn_date_time Cancellation_Date
100 8/30
101 8/31
102 9/1
103 9/1 9/1 取消 of txn 100
...
109 9/7 9/7 取消of txn 102
110 9/7
...
128 9/13 ...
...
132 9/15 9/15 取消of txn 110
...
157 9/20 9/20 取消of txn 128
以上只是例子。 由于你的主要查詢是 merchant_txn_date_time,它將只從txnID 102開始,并根據日期范圍以132停止。 但是為了考慮取消,它仍然會抓取交易取消ID 157,盡管它超出了9/15結束日期,作為內部WHERE限定符的一部分。 如前所述,取消交易總是發生在原始交易發生之后。 同樣,這是一個部分猜測,因為如果你的取消日期是tbl_master或iref表的一部分,則從未被限定,因此在整個查詢中擁有適當的alias.column參考非常重要。
此外,對這一點進行更深入的分析。 簡介ID是否會與原始交易相同? 就像一個人的銀行賬戶,你只想讓那個人的賬戶進一步限制為同一個人的個人資料ID = 28688 AND Merchant_txn_date_time >= 9/1 AND Cancellation_Date背景關系被應用。 至少,Merchant_txn_date_time >=9/1會有很大幫助。
最后,我將添加STRAIGHT_JOIN來告訴MySql按照這里具體提供的順序運行查詢
。SELECT STRAIGHT_JOIN SQL_CALC_FOUND_ROWS
tm.TXNID,
tm.MERCHANT,
tm.AMOUNT,
tm.MERCHANT_TXN_DATE_TIME,
tm.TXN_TYPE。
CONCAT(pgm.PG_COMPANY,'-',cm.CHANNEL) AS BANK
FROM
tbl_master tm
JOIN tbl_pg_rates c
ON tm. merchant_channel_pg_id = c.merchant_channel_pg_id
JOIN tbl_pg_master cpm
ON c.channel_pg_id = cpm.channel_pg_id
JOIN tbl_channel_master cm
ON cpm.CHANNELID = cm.CHANNELID
JOIN tbl_payment_gateway_master pgm
ON cpm.PGID = pgm.PGID
WHERE[/span
tm.PROFILEID = 28688
AND tm.MERCHANT_TXN_DATE_TIME >= UNIX_TIMESTAMP('2021-09-01 00:00:00')
AND tm.MERCHANT_TXN_DATE_TIME <= UNIX_TIMESTAMP('2021-09-16 23:59:59')
AND tm.TXN_STATUS = 1
AND tm. txn IN( 'netbnk', 'pg', 'ppc', 'upi')
AND tm.txnid NOT IN(
SELECT
tm2.txnid
FROM(
tbl_master tm2
JOIN tbl_irctc_refund_settled_txns iref
ON tm2.txnid = iref.txnid
WHERE
--不確定profileId是否符合我在答案中的評論。
tm2.PROFILEID = 28688
--但總是包括原始日期/時間的交易。
--應該是在你要找的主要外部限定日期之后。
AND tm2.MERCHANT_TXN_DATE_TIME >= UNIX_TIMESTAMP('2021-09-01 00:00:00')
--不需要這個>=9/1取消,因為上面會阻止任何。
--在有關日期之前開始取消。
AND tm2.CANCELLATION_DATE >= '2021-09-01'
and tm2.CANCELLATION_DATE <='2021-09-16'
and tm2. txn IN( 'netbnk', 'pg', 'ppc', 'upi')
)
LIMIT
0,2000。
為
提供了以下表格和索引tbl_master ( ProfileId, Merchant_txn_date_time, txn_status, txn, txnid, merchant_channel_pg_id ) /span>
tbl_pg_rates ( merchant_channel_pg_id, channel_pg_id )
tbl_pg_master ( channel_pg_id, CHANNELID, PGID )
-- 隱含/猜測 關于 列 列 for channel 和 pg_company for descriptions in query
tbl_channel_master ( CHANNELID, CHANNEL )
tbl_payment_gateway_master ( PGID, PG_COMPANY )
tbl_irctc_refund_settled_txns ( txnid )/span>
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/331034.html
標籤:
