首頁  >  問答  >  主體

php - 一道MySQL优化查询的面试题

前几天面试碰到一个数据库(MySQL)优化查询的问题:

说一张表里有1千万条数据,有一个字段status有两个值(1待审核、2审核通过),然后呢有两个列表即待审核列表与审核通过的列表,那么如何优化查询SQL使其列表的查询速度达到最快?

我没答上来,其实我本来想说给status字段加索引,但细想由于它的值重复性太多,即使加了索引效果也不明显,所以我不知道如何去优化这样的查询。

PHPzPHPz2772 天前1945

全部回覆(21)我來回復

  • myfey

    myfey2017-11-27 14:54:18

    同意依照不同的條件進行分批次查詢。

    回覆
    0
  • PHPz

    PHPz2017-04-10 15:45:26

    1.primary(id,stauts)
    2.更直接的是用redis的bitmap只有0和1刚好对应两个状态。

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-10 15:45:26

    用redis的bitmap应该适合这个场景

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-10 15:45:26

    看到这个问题后,我也迟疑了一会,针对如此大的数据量,问题的关键在于你如何去获取数据,总不可能一次获取获取全部吧!所以这里的优化重点在于业务方,尽量的压缩查询返回数据,只要查询的数据量小(如果业务不复杂,数据库不身是不适合处理复杂计算的),查询性能才能更高,至于楼上回答的分表/分区,个人感觉还是要看业务,综合来看,总不能说审核通过的记录从这个表在移动到另外一个表的,另外如果有需要获取全部的需求,那岂不是要连表查询,性能更低。
    至于如何让查询的数据量小,有很多做法,比如结合缓存(redis-nosql),保证mysql只处理我们需要的数据或者只是保存数据,往往业务的性能瓶颈并不在数据库,所以不要把压力放到数据库这里

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-10 15:45:26

    这其实得看到底考的是啥,莫名其妙的

    正常的做法加索引,但这种索引只有一个status的条件,显然是没有什么意义的。

    只是用db搜索的话,我觉得可以用分区分表的方式解决这个问题,待审核和审核过的分表处理,2个列表查询全拿就好了。

    回覆
    0
  • 高洛峰

    高洛峰2017-04-10 15:45:26

    可以考虑加字段,比如添加时间ctime,where的时候加上时间。

    补充下:force index 或许可以

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-10 15:45:26

    不知所云,

    说一张表里有1千万条数据,有一个字段status有两个值(1待审核、2审核通过),然后呢有两个列表即待审核列表与审核通过的列表,那么如何优化查询SQL使其列表的查询速度达到最快?

    查什么?怎么查?都没说清楚怎么优化么?待审核表与审核通过表又是啥(视图么? 表的话怎么关联的)?

    我想的是,既然题中只有两个状态,为什么不分表?

    题外:我自己做的审批系统内是这样处理的,所有发生的事件都会把(id,event_id,status,desc,url,time) 这些东西,单独弄个内存表(cache),status符合一定条件或者超时,就从这个表里删除(按时间顺序归档)了,所以不可能出现那么大的表。

    回覆
    0
  • 阿神

    阿神2017-04-10 15:45:26

    我记得上学学哲学的时候就说是一切是相对的,没有绝对论,所以这里的“最快”不是绝对的

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-10 15:45:26

    给status加哈希索引,sql语句只能是where status = 1,外加limit了

    回覆
    0
  • 迷茫

    迷茫2017-04-10 15:45:26

    mysql 没想到好的答案。。在一个表中,加索引重复太高了。。。。请高人指点吧。。。

    一般都是把这状态放到redis的list中。。。。

    回覆
    0
  • 取消回覆