InnoDB big-end问题和一个小优化

 

1、背景

  InnoDB引擎存储int类型时使用big-endian, MySQL使用litter-endian, 导致一个问题是在两个层之间拷贝int类型数据的时候必须用一个循环来处理,而不能直接memcpy。 在引擎层返回数据量很大的情况下,很耗cpu

 

       在报表类的一些查询中,会访问大量的数据。我们有个项目的一个查询需要访问到1.4wbigint,这个时候cpu的消耗就体现出来了。

 

2、相关代码

目前使用的转换代码就是使用循环。

row_sel_field_store_in_mysql_format这个函数的作用是把数据从InnoDB格式转成MySQL格式,

 

如下:

ptr = dest + len;                                            

                                                             

for (;;) {                                                    

        ptr--;                                               

        *ptr = *data;                                        

        if (ptr == dest) {                                   

                break;                                       

        }                                                    

        data++;                                              

}

 

这里如果是bigint就需要循环8次。

 

       反过来的转换代码在row_mysql_store_col_in_innobase_format,也是类似的需要一个循环。

 

3、改进和效果

这一坨循环,O3编译以后的汇编代码下,如果是bigint,需要40条指令。而显然我们使用的时候,intbigint会很多。

因此考虑当len=48的时候,使用bswapbswapq实现。

 

修改后再用oprofile观察上面说到的一个统计查询压力下的结果,发现row_sel_field_store_in_mysql_format这个函数cpu占用率从50%下降到44%.

 

DB的多数情况下压力还是在io,因此这个改进的效果需要在特定场景下才能体现。 最近跟Oracle InnoDB工程师讨论的时候了解到会有一些专门针对减少汇编结果做的优化,就凑热闹把这个提了。

Patch内容: http://bugs.mysql.com/file.php?id=18018&text=1 基于5.5.22

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值