【问题标题】:Mysql : combining multiple integer fields into one string field?Mysql:将多个整数字段组合成一个字符串字段?
【发布时间】:2012-06-26 21:12:38
【问题描述】:

假设我有一个包含数百万行的表,其中有 3 个整数变量:x、y 和 z,我在 SELECT 中对其进行搜索... WHERE x=a and y=b and z=c

哪个会更快/更高效?

  • 将 3 个字段组合成单独的字符串列“x_y_z”(例如 1231_3242_6864)并对其进行索引

  • 针对三个整数创建一个 3 列索引?

【问题讨论】:

  • 每个整数的最大值是多少?
  • 这里为了论证的目的,说每个 50 000
  • 就存储大小而言,三个UNSIGNED SMALLINT 字段总共需要6 个字节,而像12345_67890_24680 这样的字符串可能需要17 个字节。然后,相同的原则适用于索引的 RAM 使用。某些方面可以调整,但在我用 3 百万进行的快速测试中。行,一字符串表是 130 MB 数据 / 170 MB 索引,而三 Int 表是 97 MB 数据 / 76 MB 索引。
  • 这很简单:3 列和复合索引。

标签: mysql performance


【解决方案1】:

不,这将是最糟糕的,字符串比较要慢得多。你最终可以(如果真的需要,我不会推荐它)将 3 个整数组合成一个整数,但只有 如果它们适合

但是,要解决您的索引,最简单的问题是在 x、y 和 z 上创建一个复合索引

【讨论】:

  • 您不能将整数组合成一大列。想象一下 (x = 1, y = 3, z = 5) 和 (x = 5, y = 1, z = 3) 的情况,它们加起来的值相同,但含义却大不相同。
  • 不,你不会把它们加起来,但是例如 x, y, z = 3, 5, 7,结果将是 3000005000007。这就是为什么我问整数的大小
  • @Ekoo 当然你不会添加它们,但你会按照 Sebas 的说法(或将它们转换为二进制),但这取决于每个的最大大小。这就是我所说的“如果他们适合”
  • @Ekoo 1 列索引可能比 3 1 好,但 3 整数的组合可能更好,而且麻烦更少。
  • 非常正确,我猜在 95%+ 的情况下,3 int 复合就足够了。
【解决方案2】:

如果您可以有覆盖索引,并且始终提供所有三个数字,因此不必担心索引中的顺序(注意这也是字符串化版本中的一个问题),我会使用这三个数字的复合索引整数。

三个整数将占用更少的空间,使每页可以容纳更多的行,这通常会使索引在读取时更有效率。与 99999 的 5 字节字符串(+/- ~2^31 的 4 字节)相比,您在该整数中还有更多的空间。

在数据库查询中很难判断效率的大小,但请记住,您还必须组装和填充这些。不确定您计划在 MySQL 中如何或在何处执行此操作 - SQL Server 已持久化计算列,如果您要提交字符串版本,这可能是一个不错的设计选择。

当然不希望在执行连接之前将整数转换为字符串并动态连接它们。

【讨论】:

    【解决方案3】:

    我认为您确实需要自己对其进行基准测试(肯定还有其他因素会决定您对特定数据的特定查询的性能),但除了使用由提出的复合 3 列索引的想法之外@mb14。你可以试试这个:

    像这样在你的表上创建一个新列:

    xyzcomposite BINARY(16)
    

    然后,在此列上创建索引。

    在插入时,您需要执行额外的步骤来连接字符串“x_y_z”,然后像这样插入:

    INSERT INTO yourtable (...,xyzcomposite) VALUES (...,UNHEX(MD5('the_xyz_concat')));
    

    当然,您还需要在 select 语句之前运行哈希算法。

    set @xyz = UNHEX(MD5('x_y_z'));
    select * from yourtable where xyzcomposite = @xyz
    

    我不确定这些开销的总和是否值得您在只索引这一列而不是三列索引时看到的性能提升。就像我说的那样,您必须根据您的表格和数据对其进行基准测试。

    编辑:这种方法的优点是它适用于任何大小的 x、y 和 z 数字。

    【讨论】:

      【解决方案4】:

      还有一些与当前讨论相关的其他问题:

      Indexing Performance BigInt vs VarChar

      Is there a REAL performance difference between INT and VARCHAR primary keys?

      When should I use a composite index?

      从关于复合索引的问题来看,one of the answers 似乎表明如果您的 x、y 和 z 在它们之间往往是唯一的(即大多数 x 值彼此不同,等等),您就赢了无论如何都不会得到太多的性能提升。但如果他们这样做了,复合索引似乎是要走的路。

      【讨论】:

      • 不存在重叠或不取值的问题,当查询为WHERE x=a AND y=b AND z=c时,索引会高效。这个答案是关于空间搜索的查询(两个范围条件),而不是 3 个相等条件。
      • 值的重叠可能不是我正在寻找的精确短语,也许 x、y 和 z 的唯一性更准确。基本上,这个想法是索引只有在多个 x = a 时才有帮助,依此类推。
      • 当然,如果表中的所有行都有x=a和y=b和z=c,那么索引就没有多大帮助了:)这就是索引(关于查询参数)。它与索引是否有用以及是否使用有关。但这与您的链接答案无关。
      猜你喜欢
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      • 2017-04-02
      • 2017-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多