我在以下博文中发表评论,建议不要使用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?
应该避免使用中,还是应该在最能代表我存储数据的情况下继续使用?
答案 0 :(得分:9)
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])
);
}
答案 1 :(得分:3)
在宏伟的计划中,连续进行是一项巨大的成本。简单的函数,表达式以及更少的数据格式在查询所花费的时间内无关紧要。
另一方面,如果您的数据集太大而无法保持缓存,则获取行的I / O开销会更加显着。一条粗略的经验法则表明,非缓存行只需缓存10次次。因此,缩小数据集(例如使用较小的*INT
)可能会为您带来巨大的性能优势。
此参数适用于...INT
,FLOAT
vs DOUBLE
,DECIMAL(m,n)
,DATETIME(n)
等。{{1}需要进行不同的讨论}和[VAR]CHAR/BINARY(...)
。)
对于具有汇编语言背景的人......
因此,编写代码的唯一理智方法是在字节级工作,并忽略寄存器大小并假设所有值都是错误对齐的。
对于优化,按重要性排序:
经验法则:如果暂定优化没有(通过信封背面计算)产生10%的改善,不要浪费你的时间。相反,寻找更大的改进。例如,索引和汇总表通常提供10倍(不仅仅是10%)。