首页 文章

应该在mysql中避免使用mediumint吗?

提问于
浏览
11

我发现以下博客文章的评论建议不要使用mediumint:

即使在MySQL中,也不要使用[24位INT] . 这是愚蠢的,它很慢,实现它的代码是一个爬行恐怖 .

4294967295 and MySQL INT(20) Syntax Blows

stackoverflow的答案还指出SQL Server,Postgres和DB2不支持mediumint .

What is the difference between tinyint, smallint, mediumint, bigint and int in MySQL?

应该避免使用中,还是应该在最能代表我存储数据的情况下继续使用?

2 回答

  • 3

    InnoDB将MEDIUMINT存储为三个字节的值 . 但是当MySQL必须进行任何计算时,三个字节MEDIUMINT被转换为8个字节的unsigned long int(我假设现在没有人在32位上运行MySQL) .

    有利有弊,但你明白“这是愚蠢的,它很慢,实现它的代码是一种爬行的恐怖”推理不是技术性的,对吧?

    我想说当磁盘上的数据大小至关重要时,MEDIUMINT是有意义的 . 即当一个表有这么多记录,甚至一个字节的差异(4字节INT与3字节MEDIUMINT)意味着很多 . 这是一种罕见的情况,但可能 .

    mach_read_from_3和mach_read_from_4 - InnoDB用于从InnoDB记录中读取数字的原语是类似的 . 他们都返回ulint . 我打赌你不会注意到任何工作量的差异 .

    只需看看代码:

    ulint
    mach_read_from_3(
    /*=============*/
            const byte*     b)      /*!< in: pointer to 3 bytes */
    {
            ut_ad(b);
            return( ((ulint)(b[0]) << 16)
                    | ((ulint)(b[1]) << 8)
                    | (ulint)(b[2])
                    );
    }
    

    你认为它比这慢得多吗?

    ulint
    mach_read_from_4(
    /*=============*/
            const byte*     b)      /*!< in: pointer to four bytes */
    {
            ut_ad(b);
            return( ((ulint)(b[0]) << 24)
                    | ((ulint)(b[1]) << 16)
                    | ((ulint)(b[2]) << 8)
                    | (ulint)(b[3])
                    );
    }
    
  • 9

    在宏伟的计划中,取得成功是一笔巨大的成本 . 简单的函数,表达式以及更少的数据格式在查询所花费的时间内无关紧要 .

    另一方面,如果您的数据集太大而无法保持缓存,则获取行的I / O开销会更加显着 . 粗略的经验法则是,非缓存行的长度是缓存行的10倍 . 因此,缩小数据集(例如使用较小的 *INT )可能会给您带来巨大的性能优势 .

    此参数适用于 ...INTFLOAT vs DOUBLEDECIMAL(m,n)DATETIME(n) 等 . ( [VAR]CHAR/BINARY(...)TEXT/BLOB 需要进行不同的讨论 . )

    对于具有汇编语言背景的人...

    • 一个表可能混合了数字和字符串,从而阻止了对值的尝试 .

    • MySQL一直处理各种具有二进制兼容性的硬件(big / little-endian,16/32/64-bit) . 请注意@akuzminsky提供的代码如何避免对齐和字节序问题 . 如果硬件只有16位,它可以让编译器处理32位问题 .

    • 测试特殊情况的代码可能会超过简单编写通用代码 .

    • 我们说的通常不到总行处理时间的1% .

    因此,编写代码的唯一合理方法是在字节级工作,并忽略寄存器大小并假设所有值都是错误对齐的 .

    对于优化,按重要性顺序:

    • 计算磁盘命中数 . 触摸磁盘绝大多数是查询中最昂贵的部分 .

    • 计算触摸的行数 . 找到一行(通过BTree等)需要一些CPU . 但是,请注意,很少有安装是CPU限制的;那些往往指数不佳的人 . (经验法则:InnoDB数据或索引块通常有100行 . )

    • 现在才解析该行 .

    经验法则:如果暂定优化没有(通过封装后的计算)产生10%的改进,不要浪费你的时间 . 相反,寻找更大的改进 . 例如,索引和摘要表通常提供10倍(不仅仅是10%) .

相关问题