MYSQL INNODB主键使用varchar和int的区别

本文深入探讨了在MySQL InnoDB中,使用VARCHAR和INT作为主键的区别,重点关注它们在数据存储、索引效率、查询性能等方面的影响。通过源码分析,揭示了不同数据类型在内部比较过程中的实现细节,帮助读者理解选择哪种数据类型更合适。
摘要由CSDN通过智能技术生成
原创,如果有误请指出

今天同事讨论关于主键使用varchar和int的区别。

我现在总结的3个问题:
1、tablespace中空间浪费
   当然我们知道使用varchar可能会导致辅助索引比较大,因为用到varchar可能存储的字符较多,同时
   在行头也存在一个可变字段字符区域(1-2)字节
   而辅助索引叶子结点毕竟都存储了主键值,这样至少会多varchar数据字节数量+1(或者2) 字节- 4(int)字节空间。
   如果辅助索引比较多空间浪费是可想而知的。
2、辅助索引B+树扫描性能
    由于辅助索引B+树的空间要求更大,虽然在B+树层次一般都是3层-4层,索引单值定位I/O消耗并不明显,如果涉及到
    范围查询(比如PAGE_CUR_G),需要访问的块就更多,同时比如例如辅助索引的using index,需要访问的块自然
    更多
3、比较更加复杂
   innodb 在进行元组比较的时候,不管是DML,select都会涉及到元组的比较,同时回表的时候也涉及
   到比较操作。而varchar类型的比较比int类型更为复杂一些。
那么我们就来分析第三个问题,第一个问题和第二个问题是显而易见的。
我这里数据库字符集为latin1\latin1_swedish_ci

其实在innodb底层进行比较的时候都调用cmp_data这个函数
在innodb中有自己的定义的数据类型如下:

点击(此处)折叠或打开

  1. /*-------------------------------------------*/
  2. /* The 'MAIN TYPE' of a column */
  3. #define DATA_MISSING    0    /* missing column */
  4. #define    DATA_VARCHAR    1    /* character varying of the
  5. latin1_swedish_ci charset-collation; note
  6. that the MySQL format for this, DATA_BINARY,
  7. DATA_VARMYSQL, is also affected by whether the
  8. 'precise type' contains
  9. DATA_MYSQL_TRUE_VARCHAR */
  10. #define DATA_CHAR    2    /* fixed length character of the
  11. latin1_swedish_ci charset-collation */
  12. #define DATA_FIXBINARY    3    /* binary string of fixed length */
  13. #define DATA_BINARY    4    /* binary string */
  14. #define DATA_BLOB    5    /* binary large object, or a TEXT type;
  15. if prtype & DATA_BINARY_TYPE == 0, then this is
  16. actually a TEXT column (or a BLOB created
  17. with < 4.0.14; since column prefix indexes
  18. came only in 4.0.14, the missing flag in BLOBs
  19. created before that does not cause any harm) */
  20. #define    DATA_INT    6    /* integer: can be any size 1 - 8 bytes */
  21. #define    DATA_SYS_CHILD    7    /* address of the child page in node pointer */
  22. #define    DATA_SYS    8    /* system column */

我们熟悉的int类型属于DATA_INT而varchar属于DATA_VARCHAR,rowid属于DATA_SYS
在函数cmp_data根据各种类型的不同进行了不同比较的方式,这里就将int和varchar
判断的方式进行说明:
1、innodb int类型比较
实际上是在cmp_data中进行了大概的方式如下

点击(此处)折叠或打开

  1. if (len) {
  2. #if defined __i386__ || defined __x86_64__ || defined _M_IX86 || defined _M_X64
  3. /* Compare the first bytes with a loop to avoid the call
  4. overhead of memcmp(). On x86 and x86-64, the GCC built-in
  5. (repz cmpsb) seems to be very slow, so we will be calling the
  6. libc version. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43052
  7. tracks the slowness of the GCC built-in memcmp().


  8. We compare up to the first 4..7 bytes with the loop.
  9. The (len & 3) is used for "normalizing" or
  10. "quantizing" the len parameter for the memcmp() call,
  11. in case the whole prefix is equal. On x86 and x86-64,
  12. the GNU libc memcmp() of equal strings is faster with
  13. len=4 than with len=3.


  14. On other architectures than the IA32 or AMD64, there could
  15. be a built-in memcmp() that is faster than the loop.
  16. We only use the loop where we know that it can improve
  17. the performance. */
  18. for (ulint i = 4 + (len & 3); i > 0; i--) {
  19. cmp = int(*data1++) - int(*data2++);
  20. if (cmp) {
  21. return(cmp);
  22. }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值