我想通过多个属性的组合来搜索我的MYSQL数据库表,并希望为其编制索引。例如,如果这是我的桌子:
+----+--------+--------+--------+--------+
| id | field1 | field2 | field3 | field4 |
+----+--------+--------+--------+--------+
| | | | | |
我想运行以下查询:
select * from table where field1=value1 and field2=value2;
select * from table where field3=value3 and field4=value4;
select * from table where field1=value1 and field2=value2 and field3=value3;
select * from table where field4=value4;
为类似的东西建立索引的最佳方法是什么?
CREATE INDEX my_index on table(field1, field2, field3, field4);
或类似的东西:
CREATE INDEX my_index1 on table(field1);
CREATE INDEX my_index2 on table(field2);
CREATE INDEX my_index3 on table(field3);
CREATE INDEX my_index4 on table(field4);
还是其他东西?
答案 0 :(得分:0)
根据您要使用的查询类型,我建议创建索引的最佳方法是:
CREATE INDEX my_index1 on table(field1);
CREATE INDEX my_index2 on table(field2);
CREATE INDEX my_index3 on table(field3);
CREATE INDEX my_index4 on table(field4);
然后,您将创建4个可以独立使用的不同索引,否则,您将创建一个组合索引。
为什么一个索引在这里不起作用?
因为只有一个带有多个字段的索引,所以仅当您严格从左到右使用查询中的字段时,查询才会应用索引。我举了一些例子:
EXPLAIN SELECT * FROM table WHERE field2=value2 AND field1=value1;
此查询将为字段field1
和field2
应用索引。为什么?因为您正在使用创建的索引中最左边的两个字段。
您可以在explain
字段possible_keys
上看到其值为my_index
但是下一个示例:
EXPLAIN SELECT * FROM table WHERE field3=value3 AND field4=value4;
不会应用任何索引,因为您将直接从最右边调用方法。
您可以在explain
字段possible_keys
上看到其值为null
还有最后一个例子:
EXPLAIN SELECT * FROM table WHERE field1=value1 AND field4=value4;
此查询仅将索引应用于field1,而不应用于field4
。原因?不会用在其他fields2
和field3
之间。
您可以在等于{{1}的explain
字段possible_keys
和值为my_index
的字段extras
上看到它
您可以在此处找到有关综合索引的更多信息:
http://www.mysqltutorial.org/mysql-index/mysql-composite-index/
答案 1 :(得分:0)
让我们从为每个查询创建最佳索引开始:
select * from table where field1=value1 and field2=value2;
INDEX(value1, value2) -- in either order
select * from table where field3=value3 and field4=value4;
INDEX(value3, value4) -- in either order
select * from table where field1=value1 and field2=value2 and field3=value3;
INDEX(value1, value2, value3) -- in any order
select * from table where field4=value4;
INDEX(value4)
现在,让我们看看是否可以减少索引数量:
INDEX(value1, value2) -- in either order, and
INDEX(value1, value2, value3) -- in any order
可以如下组合以具有一个可以很好地处理两个选择的索引:
INDEX(value1, value2, -- in either order
value3) -- afterwards
类似地,
INDEX(value3, value4) -- in either order
INDEX(value4)
->
INDEX(value4, value3) -- in THIS order
因此,对于那些 SELECTs
,两个复合索引是最佳的:
INDEX(value1, value2, -- in either order
value3) -- afterwards
INDEX(value4, value3) -- in THIS order
但是...您提供了所有SELECTs
吗?我怀疑你没有。您实际上允许所有列的所有组合。这真的很混乱。我不建议您进行上述练习,而是建议您找到最可能的组合,构建一些复合索引,然后注意INDEX(a,b,c)
是INDEX(a,b,d)
的很好的替代,以减少组合。
但是...如果您不仅只有=
,情况还会更糟。建立综合索引时,首先要建立=
列,然后再建立任何INs
列,最后只有一个“范围”测试。
但是...如果您用的是OR
而不是AND
,那么就不要进行优化了。
经验法则:索引不得超过5个。
现在,如果您想重新开始,使用 real 列名和 real 数据类型,即 real 有意义的线索,我可以为您提供进一步的帮助。