您误解了索引的工作原理。
想想电话簿(相当于姓氏在前,名字在后的两列索引)。如果我让你在电话簿中找出所有姓“史密斯”的人,你会受益于姓名是这样排列的。您可以假设 Smiths 是组织在一起的。但是,如果我要求您查找所有名字为“John”的人,您不会从索引中受益。 Johns 可以有任何姓氏,因此他们分散在整本书中,您最终不得不从头到尾艰难地搜索。
现在,如果我要求您查找姓氏为“Smith”或名字为“John”的所有人,您可以像以前一样轻松找到 Smiths,但这对您查找 Johns 没有任何帮助.它们仍然散布在整本书中,你必须努力寻找它们。
SQL 中的多列索引也是如此。索引按第一列排序,然后在第一列相同的情况下按第二列排序,然后在前两列都相同的情况下按第三列排序,依此类推。它不是按所有列排序的同时地。因此,除了索引中最左侧的列之外,您的多列索引无助于提高搜索词的效率。
回到你原来的问题。
为此查询索引此类表的正确方法是什么?
在每列上创建一个单独的单列索引。根据 MySQL 的 estimation of how many I/O operations,其中一个索引将是比其他索引更好的选择。如果使用该索引,则会产生该索引。
现代版本的 MySQL 也有一些关于 index merging 的聪明之处,因此查询可能在给定表中使用多个索引,然后尝试合并结果。否则 MySQL 往往会被限制为在给定查询中对每个表使用一个索引。
许多人成功使用的另一个技巧是对每个索引列(应该使用相应的索引)进行单独查询,然后UNION 结果。
SELECT fields FROM table WHERE field1='something'
UNION
SELECT fields FROM table WHERE field2='something'
UNION
SELECT fields FROM table WHERE field3='something'
UNION
SELECT fields FROM table WHERE field4='something'
最后一个观察:如果您发现自己在四个字段中搜索相同的'something',您应该重新考虑所有四个字段是否实际上是相同的,并且您设计了一个violates First Normal form with repeating groups 的表。如果是这样,也许 field1 到 field4 属于子表中的单个列。那么索引和查询就变得容易多了:
SELECT fields from table INNER JOIN child_table ON table.pk = child_table.fk
WHERE child_table.field = 'something'