SELECT * FROM user LIMIT 10000,1.
这条语句有很大问题,请优化它!并解释出现查询问题的原因?
SELECT * FROM user LIMIT 10000,1.
这条语句有很大问题,请优化它!并解释出现查询问题的原因?
这句话相当于 select * from user offset 10000 limit 1
myql中offset会占用大量的时间来查找,但是你这个语句中又不需要他,又会把他抛掉,造成没必要的问题。
应该先找到 10000条中最后那一条的主键,假设值就是 10000
select * from user where id > 10000 limit 1
通过主键的索引来快速定位,可以减少查询时间
2 回答2.5k 阅读✓ 已解决
5 回答1.5k 阅读
2 回答1.1k 阅读✓ 已解决
2 回答2.2k 阅读
1 回答1.6k 阅读✓ 已解决
3 回答746 阅读✓ 已解决
1 回答845 阅读✓ 已解决
如果我去面试,我会这样答。
1.
select *
很有可能返回不需要的列,如果可以指定具体需要哪些列会更好,减少结果集整体大小。2.
limit 10000,1
,分不同情况的优化。对于user表主键id是连续的,可以改写
select id,username,age from user where id > 10000 limit 1
对于user表主键id有断层的,对于
select * from user limit 10000,1
是没有优化空间的。要优化,必须加where条件,例如select id,username,age from user where user_city='广州' limit 10000,1
,这样就可以改写成select id,username,age from user a inner join (select id from user where user_city='广州' limit 10000,1) b on a.id=b.id
,但要配合覆盖索引idx(user_city)才有效果,优化的思想是先从比user表小的覆盖索引上获取到主键id,再回表到主键索引里获取其他列的数据。3.在大多数情况下,主键id很有可能是断层的,而且假设实际需求就是
select * from user limit 10000,1
,加了where条件就不符合需求。那么这种情况下,就只能对表结构和表数据下手了,想办法将行数据大小减少,例如恰当地将varchar换成int,按照三范式减少数据冗余等,目的是使得每一个数据页能装下更多的行数据,即使全表扫描,读取尽可能少的数据页。4.从
SELECT * FROM user LIMIT 10000,1
来看,就是简单的获取user表第10001条数据,看不到有什么实质的查询意义,而且对于select id,username from user limit 10000,1
,这样在username列上有索引和无索引会使得返回结果集有可能是不一样的,应该结合业务逻辑来看看有没有优化空间。