84669 person learning
152542 person learning
20005 person learning
5487 person learning
7821 person learning
359900 person learning
3350 person learning
180660 person learning
48569 person learning
18603 person learning
40936 person learning
1549 person learning
1183 person learning
32909 person learning
前几天面试碰到一个数据库(MySQL)优化查询的问题:
说一张表里有1千万条数据,有一个字段status有两个值(1待审核、2审核通过),然后呢有两个列表即待审核列表与审核通过的列表,那么如何优化查询SQL使其列表的查询速度达到最快?
我没答上来,其实我本来想说给status字段加索引,但细想由于它的值重复性太多,即使加了索引效果也不明显,所以我不知道如何去优化这样的查询。
学习是最好的投资!
Agree to query in batches based on different conditions.
1.primary(id,stauts) 2.更直接的是用redis的bitmap只有0和1刚好对应两个状态。
用redis的bitmap应该适合这个场景
看到这个问题后,我也迟疑了一会,针对如此大的数据量,问题的关键在于你如何去获取数据,总不可能一次获取获取全部吧!所以这里的优化重点在于业务方,尽量的压缩查询返回数据,只要查询的数据量小(如果业务不复杂,数据库不身是不适合处理复杂计算的),查询性能才能更高,至于楼上回答的分表/分区,个人感觉还是要看业务,综合来看,总不能说审核通过的记录从这个表在移动到另外一个表的,另外如果有需要获取全部的需求,那岂不是要连表查询,性能更低。 至于如何让查询的数据量小,有很多做法,比如结合缓存(redis-nosql),保证mysql只处理我们需要的数据或者只是保存数据,往往业务的性能瓶颈并不在数据库,所以不要把压力放到数据库这里
这其实得看到底考的是啥,莫名其妙的
正常的做法加索引,但这种索引只有一个status的条件,显然是没有什么意义的。
只是用db搜索的话,我觉得可以用分区分表的方式解决这个问题,待审核和审核过的分表处理,2个列表查询全拿就好了。
可以考虑加字段,比如添加时间ctime,where的时候加上时间。
补充下:force index 或许可以
不知所云,
查什么?怎么查?都没说清楚怎么优化么?待审核表与审核通过表又是啥(视图么? 表的话怎么关联的)?
我想的是,既然题中只有两个状态,为什么不分表?
题外:我自己做的审批系统内是这样处理的,所有发生的事件都会把(id,event_id,status,desc,url,time) 这些东西,单独弄个内存表(cache),status符合一定条件或者超时,就从这个表里删除(按时间顺序归档)了,所以不可能出现那么大的表。
我记得上学学哲学的时候就说是一切是相对的,没有绝对论,所以这里的“最快”不是绝对的
给status加哈希索引,sql语句只能是where status = 1,外加limit了
status
mysql 没想到好的答案。。在一个表中,加索引重复太高了。。。。请高人指点吧。。。
一般都是把这状态放到redis的list中。。。。
Agree to query in batches based on different conditions.
1.primary(id,stauts)
2.更直接的是用redis的bitmap只有0和1刚好对应两个状态。
用redis的bitmap应该适合这个场景
看到这个问题后,我也迟疑了一会,针对如此大的数据量,问题的关键在于你如何去获取数据,总不可能一次获取获取全部吧!所以这里的优化重点在于业务方,尽量的压缩查询返回数据,只要查询的数据量小(如果业务不复杂,数据库不身是不适合处理复杂计算的),查询性能才能更高,至于楼上回答的分表/分区,个人感觉还是要看业务,综合来看,总不能说审核通过的记录从这个表在移动到另外一个表的,另外如果有需要获取全部的需求,那岂不是要连表查询,性能更低。
至于如何让查询的数据量小,有很多做法,比如结合缓存(redis-nosql),保证mysql只处理我们需要的数据或者只是保存数据,往往业务的性能瓶颈并不在数据库,所以不要把压力放到数据库这里
这其实得看到底考的是啥,莫名其妙的
正常的做法加索引,但这种索引只有一个status的条件,显然是没有什么意义的。
只是用db搜索的话,我觉得可以用分区分表的方式解决这个问题,待审核和审核过的分表处理,2个列表查询全拿就好了。
可以考虑加字段,比如添加时间ctime,where的时候加上时间。
补充下:force index 或许可以
不知所云,
查什么?怎么查?都没说清楚怎么优化么?待审核表与审核通过表又是啥(视图么? 表的话怎么关联的)?
我想的是,既然题中只有两个状态,为什么不分表?
题外:我自己做的审批系统内是这样处理的,所有发生的事件都会把(id,event_id,status,desc,url,time) 这些东西,单独弄个内存表(cache),status符合一定条件或者超时,就从这个表里删除(按时间顺序归档)了,所以不可能出现那么大的表。
我记得上学学哲学的时候就说是一切是相对的,没有绝对论,所以这里的“最快”不是绝对的
给status加哈希索引,sql语句只能是where
status
= 1,外加limit了mysql 没想到好的答案。。在一个表中,加索引重复太高了。。。。请高人指点吧。。。
一般都是把这状态放到redis的list中。。。。