在MySQL上创建数据库索引的最佳方法

时间:2019-02-21 10:20:52

标签: mysql database indexing

我想通过多个属性的组合来搜索我的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); 

还是其他东西?

2 个答案:

答案 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;

此查询将为字段field1field2应用索引。为什么?因为您正在使用创建的索引中最左边的两个字段。

您可以在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。原因?不会用在其他fields2field3之间。

您可以在等于{{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 有意义的线索,我可以为您提供进一步的帮助。