成佛的小兔几
2020-03-16 23:41
TbUser one = new LambdaQueryChainWrapper<>(tbUserMapper) .select(TbUser::getUserId, TbUser::getNickname) .eq(TbUser::getUserId, 1239563848215904258L).one();
逻辑删除的字段是deleted
但是我发现执行的时候打印的SQL是
SELECT user_id,nickname FROM tb_user WHERE deleted=0 AND user_id = ?
deleted条件自动放在了最前面,这样对大数据量查询性能不会有负面影响吗?
按照我看到过的文章,说sql是从右向左解析的,能够排除最大量数据的条件应该放在最右面。你那句明显应该是user_id = ?这个条件过滤掉的数据最多。单单从这条语句来说,deleted=0放在最前面是对的。但是其他情况则不一定,我目前了解的mp,这个逻辑删除字段的位置还不能修改,你可以去MP官方群里咨询一下作者,看看能否解决。或者在github或gitee上提问。
以本人愚见,MySQL对语句的执行是有优化的。MySQL会对执行的语句进行处理,生成多种执行方案,然后选取成本最低的方案。下面是两条语句的执行计划:
mysql> explain SELECT * FROM user WHERE id = 1088248166370832385 and deleted =0\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user
partitions: NULL
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: const
rows: 1
filtered: 100.00
Extra: NULL
mysql> explain SELECT * FROM user WHERE deleted=0 AND id = 1088248166370832385\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user
partitions: NULL
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: const
rows: 1
filtered: 100.00
Extra: NULL
两个的执行计划是一样的。它们的效率应该会相等吧。
你的需求是大数据量,那么肯定会分页,这个时候先后顺序其实影响不大。如果非要说性能的话,其实你多了一个deleted=0 条件性能肯定有损耗,因为你这条SQL语句如果没有逻辑删除这个功能的话直接走的是主键索引user_id(主键)当然性能最好。如果对性能问题很介意,你可以自定义SQL查询,它不走逻辑删除。其实,逻辑删除的目的是为了数据安全,我们需要做出选择,在安全和性能中找到平衡。希望可以帮到你。
MyBatis-Plus进阶
23296 学习 · 118 问题
相似问题