哪个更快:char(1)还是tinyint(1)?为什么?

Dev*_*ner 26 mysql char tinyint

我的平台:

PHP和mySQL

我的情况:

我遇到了一种情况,我需要在表格的一列中存储用户选择的值.现在我的选择是:

  1. 将Column声明为char(1)并将值存储为'y'或'n'
  2. 或者将Column声明为tinyint(1)并将值存储为1或0
  3. 如此声明的此列也可以编入索引以在应用程序中使用.

我的问题:

所以我想知道,以上两种类型中的哪一种:

  1. 访问该列时,可以提高查询速度(为简单起见,请不要混淆其他查询或访问其他列).

  2. 是最有效的存储和访问数据的方式,为什么?

  3. 如果列被索引,那么访问速度如何变化?

我的理解是,由于char(1)和tinyint(1)只占用1个字节的空间,因此在这种情况下存储空间不会成为问题.然后剩下的就是访问速度.据我所知,数字索引比其他任何东西都更快,更有效.但我认为,这里的情况很难决定.肯定希望听到你对这一次的体验.

先感谢您.

Gle*_*rry 37

                       Rate insert tinyint(1) insert char(1) insert enum('y', 'n')
insert tinyint(1)     207/s                --            -1%                  -20%
insert char(1)        210/s                1%             --                  -19%
insert enum('y', 'n') 259/s               25%            23%                    --
                       Rate insert char(1) insert tinyint(1) insert enum('y', 'n')
insert char(1)        221/s             --               -1%                  -13%
insert tinyint(1)     222/s             1%                --                  -13%
insert enum('y', 'n') 254/s            15%               14%                    --
                       Rate insert tinyint(1) insert char(1) insert enum('y', 'n')
insert tinyint(1)     234/s                --            -3%                   -5%
insert char(1)        242/s                3%             --                   -2%
insert enum('y', 'n') 248/s                6%             2%                    --
                       Rate insert enum('y', 'n') insert tinyint(1) insert char(1)
insert enum('y', 'n') 189/s                    --               -6%           -19%
insert tinyint(1)     201/s                    7%                --           -14%
insert char(1)        234/s                   24%               16%             --
                       Rate insert char(1) insert enum('y', 'n') insert tinyint(1)
insert char(1)        204/s             --                   -4%               -8%
insert enum('y', 'n') 213/s             4%                    --               -4%
insert tinyint(1)     222/s             9%                    4%                --
Run Code Online (Sandbox Code Playgroud)

似乎在大多数情况enum('y', 'n')下插入更快.

                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        188/s             --               -7%                   -8%
select tinyint(1)     203/s             8%                --                   -1%
select enum('y', 'n') 204/s             9%                1%                    --
                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        178/s             --              -25%                  -27%
select tinyint(1)     236/s            33%                --                   -3%
select enum('y', 'n') 244/s            37%                3%                    --
                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        183/s             --              -16%                  -21%
select tinyint(1)     219/s            20%                --                   -6%
select enum('y', 'n') 233/s            27%                6%                    --
                       Rate select tinyint(1) select char(1) select enum('y', 'n')
select tinyint(1)     217/s                --            -1%                   -4%
select char(1)        221/s                1%             --                   -2%
select enum('y', 'n') 226/s                4%             2%                    --
                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        179/s             --              -14%                  -20%
select tinyint(1)     208/s            17%                --                   -7%
select enum('y', 'n') 224/s            25%                7%                    --
Run Code Online (Sandbox Code Playgroud)

选择似乎也是enum.代码可以在这里找到


Iva*_*uev 31

我认为你应该创建列ENUM('n','y').Mysql以最佳方式存储此类型.它还可以帮助您在字段中仅存储允许的值.

您还可以使其更加人性化,ENUM('no','yes')而不会影响性能.因为字符串'no''yes'每个ENUM定义只存储一次.Mysql只存储每行值的索引.

还要注意按ENUM列排序:

ENUM值是根据在其中枚举成员在列说明书中列出的顺序进行排序."A"排序之前"B"为ENUM(换句话说,ENUM值根据其指数数字排序.)例如,("A","B"),但在此之前的"A"为ENUM"B"各种各样('b','a').

  • 回过头来的时候,我和OP有同样的问题,我对它进行了基准测试,以找到三种选择中最快最有效的枚举.只要确保你不像我那样使用枚举('0','1') - 你最终会想知道为什么UPDATE X SET Y = 0; 不起作用(你需要单引号). (10认同)

Mat*_*chu 10

使用tinyint是更标准的做法,并且可以让您更轻松地检查字段的值.

// Using tinyint 0 and 1, you can do this:
if($row['admin']) {
    // user is admin
}

// Using char y and n, you will have to do this:
if($row['admin'] == 'y') {
    // user is admin
}
Run Code Online (Sandbox Code Playgroud)

我不是MySQL内部工作的专家,但它直觉地认为检索和排序整数字段比字符字段更快(我只是感觉'a'>'z'更多的工作0> 1)从计算角度来看,似乎更为熟悉,其中0和1是标准的开/关标志.因此整数的存储似乎更好,感觉更好,并且更容易在代码逻辑中使用.0/1对我来说是明显的赢家.

您可能还注意到,在某种程度上,这也是MySQL的官方立场,来自他们的文档:

BOOL,BOOLEAN:这些类型是TINYINT(1)的同义词.值为零被视为false.非零值被认为是真实的.

如果MySQL将TINYINT(1)与BOOLEAN等同起来,那么它似乎就是要走的路.