mysql什么分表?以及我什么知道该去哪个表取数据?

回复列表(157|隐藏机器人聊天)
  • @Ta / 2022-06-27 / /
    @无名啊,你是真狠,了解的这么底层。
  • @Ta / 2022-06-27 / /

    @大尨,这是你有性能问题的那个表吗

  • @Ta / 2022-06-27 / /

    @大尨,我不了解啊,今天刚查的,我是数据库上手一两年的新手

    @老虎会游泳 对我几个概念说几句后,我都马上怀疑我的想法了,典型的不熟悉

  • @Ta / 2022-06-27 / /
    @老虎会游泳,不是,那个事新要搞鼓的东西。类似的业务之前的经验差不多这样的数据体验就不行。所以要找办法。
  • @Ta / 2022-06-27 / /
    @老虎会游泳

    show table status like 'hu60_bbs_topic_content'
    


    看这个数据好像也没啥用啊
  • @Ta / 2022-06-27 / /

    @大尨,哦好吧。那么根据 @无名啊 的计算,如果你能把有着大量实际内容的字段(比如extend)从这个表分离出去,就可以让表存储更多行的数据而不产生性能下降。

    当然,创建正确的索引也很重要。我觉得创建一个 key uid_type(uid, type) 就足够了,是在大小和速度方面都平衡的选择。

  • @Ta / 2022-06-27 / /

    @大尨,我们想看你的Avg_row_length(平均记录大小),以找到性能下降的真正原因。但是你并没有实际数据,所以确实没用。

  • @Ta / 2022-06-27 / /

    @大尨,当然分表也是解决性能问题的好办法。而且减小平均记录大小只能优化一次,分表则是可扩展的,想优化几次就能优化几次。

    鉴于你没有实际数据,我建议你用脚本创建一些测试数据用来实验,看看什么方法适合你。这样可能比理论分析更有说服力。

  • @Ta / 2022-06-27 / /
    1656269336274.jpg

    @老虎会游泳,刚才我去查询了一个三百多万数据的表,InnoDB的count(*) 操作第一次查询挺慢的,第二次只会才会快一些这个,这个该什么优化?
  • @Ta / 2022-06-27 / /

    @大尨,如果你真的想优化count(*),就为变化程度最低(重复率最高)的某个字段创建一个索引。但是通常没有必要优化它吧,因为很少进行全表count(*)操作,通常的count(*)都是带条件的,你只需要为这个条件创建索引即可快速得到结果。

  • @Ta / 2022-06-27 / /

    @老虎会游泳

    如果你能把有着大量实际内容的字段(比如extend)从这个表分离出去,就可以让表存储更多行的数据而不产生性能下降

    也不知@大尨 是否每次都要这个extend,若是的话,还是不用分离了吧,B+树多一层就多一层呗,比“再去查多一棵树来取得extend”好

  • @Ta / 2022-06-27 / /
    @老虎会游泳,这样?

    
    $count = DB::table("ulogs")->where("id",">",0)->count();
    
    //  SELECT COUNT(*) FROM `ulogs` WHERE id > 0
    
    

  • @Ta / 2022-06-27 / /

    @老虎会游泳@大尨

    当然分表也是解决性能问题的好办法。而且减小平均记录大小只能优化一次,分表则是可扩展的,想优化几次就能优化几次

    确实,分表能大幅减少一个表的行数,应该作为主要手段?(毕竟有extend在,行记录的平均长度减不到哪儿去了)

  • @Ta / 2022-06-27 / /
    @无名啊,分出去 然后 再去查多一棵树来取,好像又多出不少活啊。。
  • @Ta / 2022-06-27 / /

    @大尨,我觉得,看你取行数据时,是否经常也要用到extend?是的话,没必要拆表?

  • @Ta / 2022-06-27 / /

    @大尨,举个例子,对于

    $count = DB::table("ulogs")->where("uid","=",1)->count();
    

    如果你在uid上有一个索引,那么可以瞬间得到结果。

    但是对于

    $count = DB::table("ulogs")->where("id",">",0)->count();
    

    你在id上有索引(它是主键,主键是索引)也没用,这个索引太大了,所以还是得扫描很久。但是如果你在type字段上有索引,不加条件的话就能应用这个索引,反而更快。这就是“给不怎么变化的字段加索引可以优化count(*)”。

    再举个例子,如果你有一个始终为0的字段,你给它加个索引,那应该就能立即获得全表count(*)的结果了,因为结果可以直接从这个索引里读取。

    注意:没有必要为了优化count(*)而去专门添加一个不变的字段,不值得。

  • @Ta / 2022-06-27 / /

    @老虎会游泳,自增主键的索引(即,聚簇索引?),应该算很小的索引了吧?

    真的还会比这个快吗(tinyint字段啥的先排除)

  • @Ta / 2022-06-27 / /

    @无名啊,让mysql自己告诉我们吧:

    Screenshot_20220627_101549.jpg

    Screenshot_20220627_101522.jpg


    它选的不是key(id),而是key(topic_id),因为后者的变化比前者小多了(前者无重复,后者大量重复)。

  • @Ta / 2022-06-27 / /

    @无名啊,我给变化更少的review创建索引之后:

    create index review on hu60_bbs_topic_content(review)
    

    Screenshot_20220627_102056.jpg


    它马上就改用review了,这个只有0、1、2三种取值,想统计数量很快就能得到结果。

  • @Ta / 2022-06-27 / /

    @无名啊,不过它也不是特别智能。比如我给变化更少的access(只有0、1)创建索引,它就没有使用,还是继续使用key(topic_id)。看起来上面让它改用key(review)的原因是其key_len更小。但可以肯定的是,如果有其他索引,MySQL不会考虑使用主键,因为统计主键数量需要全表扫描。

    create index access on hu60_bbs_topic_content(access)
    

    Screenshot_20220627_103034.jpg

    Screenshot_20220627_103054.jpg

添加新回复
回复需要登录