Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL中是否应该避免使用MediumIT?_Mysql_Sqldatatypes - Fatal编程技术网

MySQL中是否应该避免使用MediumIT?

MySQL中是否应该避免使用MediumIT?,mysql,sqldatatypes,Mysql,Sqldatatypes,我在下面的博客帖子上看到一条评论,建议不要使用MEDIUMINT: 即使在MySQL中也不要使用[24位INT]。它很蠢,速度也很慢,实现它的代码令人毛骨悚然 关于堆栈溢出的回答还指出,SQL Server、PostgreSQL和DB2不支持MEDIUMINT: 应避免使用MEDIUMINT,还是在最能代表我存储的数据的情况下继续使用它?InnoDB将MEDIUMINT存储为三字节值。 但是当MySQL必须进行任何计算时,三个字节的MEDIUMINT被转换成八个字节的无符号长int(我假设

我在下面的博客帖子上看到一条评论,建议不要使用
MEDIUMINT

即使在MySQL中也不要使用[24位INT]。它很蠢,速度也很慢,实现它的代码令人毛骨悚然

关于堆栈溢出的回答还指出,SQL Server、PostgreSQL和DB2不支持
MEDIUMINT



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

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

有优点也有缺点,但是你知道“它很愚蠢,而且很慢,实现它的代码是一个爬行的恐怖”的推理不是技术性的,对吗

我想说,当磁盘上的数据大小至关重要时,MEDIUMINT是有意义的。也就是说,当一个表有如此多的记录,甚至一个字节的差异(4字节INT vs 3字节MEDIUMINT)都意味着很多。这是一个相当罕见的病例,但有可能

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

请看一下代码:

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
马赫数从3读出(
/*=============*/
常量字节*b)/*!return(((ulint)(b[0])在总体方案中,获取一行是巨大的成本。简单的函数、表达式,更不用说数据格式,对于查询所需的时间来说是无关紧要的

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

此参数适用于
…INT
FLOAT
vs
DOUBLE
十进制(m,n)
日期时间(n)
,等等。(需要对
[VAR]字符/二进制(…)
文本/BLOB
进行不同的讨论)

对于那些有汇编语言背景的人

  • 表可能混合了数字和字符串,从而阻止了“对齐”值的尝试
  • MySQL一直处理各种二进制兼容的硬件(大/小尾端,16/32/64位)。请注意@akuzminsky提供的代码如何避免对齐和尾端问题。如果硬件只有16位,它还允许编译器处理32位问题
  • 测试特殊情况的代码可能比简单编写通用代码更重要
  • 我们所说的通常不到总行处理时间的1%
因此,编写代码的唯一合理方法是在字节级别工作,忽略寄存器大小,并假设所有值都不对齐

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

  • 计算磁盘点击次数。触摸磁盘绝对是查询成本最高的部分
  • 计算所接触的行数。查找一行(通过BTree等)需要一些CPU。但是,请注意,很少有安装是CPU限制的;这些安装往往具有较差的索引。(经验法则:InnoDB数据或索引块中通常有100行。)
  • 直到现在,解析行才起作用

  • 经验法则:如果一个尝试性的优化(通过信封背面的计算)不能产生10%的改进,不要在上面浪费时间。相反,寻找一些更大的改进。例如,索引和汇总表通常提供10倍(而不仅仅是10%).

    这是错误的经济。现代处理器的自然宽度是32或64位,数据库必须付出额外的努力来强制执行24位整数宽度。@JimGarrison我真的怀疑这在很大程度上是一个因素。它可以在内存中存储为32位(或不是,但这并不重要),在记录中存储为24位。(在一个int上节省多达25%的空间…)好的,谢谢。我想我是想确认MySQL在内部处理mediumint的方式是否有什么特别糟糕的地方,或者它是否真的是非标准的,应该避免使用。如果它适合存储的数据,听起来使用它很好。嗨,你的意思是,如果我使用这个:
    min(mediumnitfield)
    在MySQL中,结果将是8个字节,在java中,例如,我需要一个
    long
    type变量?由客户端库决定使用哪种类型的结果。谢谢,那么MySQL
    MEDIUMINT
    (3个字节)呢整数?它会导致CPU做额外的工作来对齐寄存器上的数据吗?这就是@accounterم告诉我的-我的背景使我非常理解“单词对齐”。但是,我声称,在这种情况下,它真的是无关紧要的。我在我的答案中添加了一些内容。
    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])
                    );
    }