查询2是
不
最优的。转动索引:
INDEX(tx_type, report_date)
也就是说,用
=
第一
,与基数无关。
IN ( SELECT ... )
是
不
一
JOIN
. (在较新版本中,
可以
转换为
加入
)
试试看:
SELECT d.*
FROM t_settle_trx AS s
JOIN t_deposit_trx AS d ON s.tx_id = d.remit_tx_id
WHERE s.tx_type = 'CANCEL'
AND s.report_date >= '2019-03-01'
AND s.report_date < '2019-03-01' + INTERVAL 2 DAY
s: INDEX(tx_type, report_date, tx_id)
d: INDEX(remit_tx_id)
想想这个
SELECT
用一个
加入
从一张桌子开始
WHERE
条款.
(注意:我排列了表和where子句的顺序,这样您就可以看到优化器是如何思考的。表的顺序和where子句的顺序不相关;优化器将根据需要重新排列。)
我的公式应该
-
充分利用两个表上的索引。
-
避免全表扫描
-
对
第一
它查看的表
全表扫描是
不
必然是件坏事。如果
最
一张桌子无论如何都会被触摸,实际上
更快
只需扫描表,而不在索引的btree和数据的btree之间跳转。(你的
具体的
凯斯还有其他不足之处,我把重点放在了这些方面。)
INDEX(tx_type, report_date, tx_id)
是“覆盖”的,因为查询所需的所有列都在一个索引中找到。覆盖“给你一个稍微额外的性能提升。它显示在
EXPLAIN
通过
Using index
(不是)
Using index condition
)
对于tx_seq,这可能是最佳的:
INDEX(tx_type, report_date, tx_seq)