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

时间:2010-01-07 20:40:01

标签: mysql char tinyint

我的平台:

PHP& mySQL的

我的情况:

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

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

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

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

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

    3. 如果列被编入索引,而不是列,则访问速度如何变化?

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

      提前谢谢。

8 个答案:

答案 0 :(得分:36)

                       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%                --

似乎在大多数情况下,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%                    --

选择似乎也是enum。代码可以是found here

答案 1 :(得分:30)

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

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

还要注意按ENUM列排序:

  

ENUM值根据列规范中列出的枚举成员的顺序进行排序。 (换句话说,ENUM值根据它们的索引号进行排序。)例如,'a'在'b'之前对ENUM('a','b')排序,但'b'在'a'之前排序为ENUM ('b','a')。

答案 2 :(得分: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
}

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

您可能还会注意到,在某种程度上,这也是MySQL的官方立场,来自their documentation

  

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

如果MySQL将TINYINT(1)与BOOLEAN等同起来,那么它似乎就好了。

答案 3 :(得分:4)

要确定这一点,你应该对它进行基准测试。或者知道在整个项目的宏观视野中,这可能并不重要。

Char列有编码和排序,比较它们可能涉及编码之间不必要的切换,所以我的猜测是int会更快。出于同样的原因,我认为更新int列的索引也更快。但同样,这并不重要。

CHAR占用多个字节,具体取决于您选择的字符集和表格选项。有些字符可能需要三个字节进行编码,因此即使您只使用yn,MySQL有时会保留该空格。

答案 4 :(得分:2)

它们都会如此接近以至于无关紧要。如果您觉得必须在SO上提出这个问题,那么您就过度优化了。使用最具逻辑意义的人。

答案 5 :(得分:1)

如果在MySQL中创建表时将类型BOOLBOOLEAN指定为列类型,则会将列类型创建为TINYINT(1)。据推测,这是两者中较快的一个。

Documentation

此外:

  

我们打算实现完整的布尔值   类型处理,按照   标准SQL,在未来的MySQL中   释放。

答案 6 :(得分:1)

虽然我的预感是TINYINT上的索引比CHAR(1)上的索引更快,因为没有字符串处理开销(整理,空格等),我没有任何支持这一点的事实。我的猜测是,没有值得担心的显着性能差异。

但是,因为你正在使用PHP,所以存储为TINYINT会更有意义。使用1/0值相当于使用truefalse,即使它们作为字符串返回给PHP,也可以这样处理。您只需将结果作为布尔检查进行if ($record['field']),而不是始终在'y'和'n'之间进行转换。

答案 7 :(得分:0)

 TINYINT    1 Byte
CHAR(M)     M Bytes, 0 <= M <= 255

有什么不同吗?