簡體   English   中英

索引 mysql 鍵 select

[英]Index mysql key select

我需要幫助來執行此查詢

SELECT *
 FROM transactions 
WHERE created_at BETWEEN '2022-08-25 01:03:21' AND '2022-12-13 01:03:21'
 AND ((transaction_reason IN ('ORIGINAL','REVERSAL_OF_ADJUSTMENT') 
 AND type = 'DEPOSIT') 
OR (transaction_reason IN ('ADJUSTMENT','REVERSAL_OF_ORIGINAL') 
 AND type = 'WITHDRAWAL') )
ORDER BY transaction_id ASC

主鍵:ID

外鍵:transaction_id

解釋

ID 選擇類型 桌子 分區 類型 可能的鍵 鑰匙 密鑰長度 參考 過濾 額外的
1個 簡單的 交易 全部 idx_transactions_dd 18356060 18:00 在哪里使用; 使用文件排序

鍵是 null,我的索引是 idx_transactions_dd (created_at,transaction_reason, type)

有什么建議嗎?

我需要創建一個新索引或修改查詢

您需要列(type, created_at)(type, transaction_reason)上的索引。

然后重構查詢。 不要在 WHERE 子句中使用OR ,而是運行兩個查詢並UNION它們各自的結果:

SELECT *
FROM transactions 
WHERE type = 'DEPOSIT' 
 AND created_at BETWEEN '2022-08-25 01:03:21' AND '2022-12-13 01:03:21'
 AND transaction_reason IN ('ORIGINAL','REVERSAL_OF_ADJUSTMENT'))
UNION 
SELECT *
FROM transactions
WHERE type = 'WITHDRAWAL'
 AND transaction_reason IN ('ADJUSTMENT','REVERSAL_OF_ORIGINAL') 
ORDER BY transaction_id ASC;

您不能在同一個 WHERE 子句中同時優化BETWEENIN 兩者都是范圍條件。 一個索引只能支持一個范圍條件(盡管現在在 MySQL 8.0 中支持跳過掃描范圍優化)。

由於IN等同於OR ,因此使用UNION進一步拆分查詢。

假設不會有任何重復,從UNION更改為UNION ALL

該索引對於所有 3 個選擇都是最佳的:

INDEX(type, transaction_reason, created_at)

工會:

( SELECT *
    FROM transactions 
    WHERE type = 'DEPOSIT' 
      AND transaction_reason = 'ORIGINAL'
      AND created_at BETWEEN '2022-08-25 01:03:21' AND '2022-12-13 01:03:21'
) UNION ALL
( SELECT *
    FROM transactions 
    WHERE type = 'DEPOSIT' 
      AND transaction_reason = 'REVERSAL_OF_ADJUSTMENT'
      AND created_at BETWEEN '2022-08-25 01:03:21' AND '2022-12-13 01:03:21'
) UNION ALL
    SELECT *
    FROM transactions
    WHERE type = 'WITHDRAWAL'
      AND transaction_reason IN ('ADJUSTMENT', 'REVERSAL_OF_ORIGINAL')
) 
ORDER BY transaction_id ASC;

(我添加了括號以闡明您希望ORDER BY應用於UNION的結果,而不是最后一個SELECT 。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM