假设我有一个包含数百万行的表,其中有 3 个整数变量:x、y 和 z,我在 SELECT 中对其进行搜索... WHERE x=a and y=b and z=c
哪个会更快/更高效?
将 3 个字段组合成一个单独的字符串列“x_y_z”(例如 1231_3242_6864)并为其编制索引
针对三个整数创建一个 3 列索引?
假设我有一个包含数百万行的表,其中有 3 个整数变量:x、y 和 z,我在 SELECT 中对其进行搜索... WHERE x=a and y=b and z=c
哪个会更快/更高效?
将 3 个字段组合成一个单独的字符串列“x_y_z”(例如 1231_3242_6864)并为其编制索引
针对三个整数创建一个 3 列索引?
不,这将是最糟糕的,字符串比较要慢得多。您最终可以(如果真的需要,我不会推荐它)将 3 个整数组合成一个整数,但前提是它们FIT。
但是,要解决您的索引,最简单的问题是在 x、y 和 z 上创建复合索引。
如果您可以有覆盖索引,并且始终提供所有三个数字,因此不必担心索引中的顺序(注意这也是字符串化版本中的一个问题),我会使用三个整数的复合索引。
这三个整数将占用更少的空间,使每页可以容纳更多的行,这通常会使索引在读取时更有效率。与 99999 的 5 字节字符串(+/- ~2^31 的 4 字节)相比,您在该整数中还有更多的空间。
在数据库查询中很难判断效率的大小,但请记住,您还必须组装和填充这些。不确定您计划在 MySQL 中如何或在何处执行此操作 - SQL Server 已持久化计算列,如果您要提交字符串版本,这可能是一个不错的设计选择。
当然,人们不想在执行连接之前将整数转换为字符串并在运行中将它们连接起来。
还有一些与当前讨论相关的其他问题:
INT 和 VARCHAR 主键之间是否存在真正的性能差异?
从关于复合索引的问题来看,其中一个答案似乎表明,如果您的 x、y 和 z 在它们之间往往是唯一的(即大多数 x 值彼此不同,依此类推),您将不会无论如何都会得到很大的性能提升。但如果他们这样做了,综合指数似乎是要走的路。
我认为您确实需要自己对其进行基准测试(肯定还有其他因素会决定您对特定数据的特定查询的性能),但除了使用@mb14 提出的复合 3 列索引的想法之外。你可以试试这个:
在您的表上创建一个新列,如下所示:
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 数字。