0

我有一个项目表,每个项目都有一个 a_level、b_level 和一个 item_id。任何 b_level 仅专用于一个 a_level(例如:b_level 14 仅是 a_level 2 的“子级”)

假设我们有数百万个项目,所有项目都插入一次,然后只请求 SELECT。

如果我根据 item_id 选择一个项目,那么我需要索引 item_id 列。这将使 MySQL 查看所有数百万个项目,这很糟糕,因为我已经有了 a_level 和 b_level 信息。所以我想如果我根据特定级别选择一个项目并且我在该列上有一个索引,那么 MySQL 将不必查看所有数百万个项目,只需查看具有该特定级别的项目。

如果我在 a_level、b_level(当然还有 item_id)和 SELECT WHERE a_level= b_level= item_id= 上都进行索引,会不会很糟糕?我想只有 b_level 和 item_id 上的 INDEX 和 SELECT WHERE b_level= AND item_id= 就足够了/最好的解决方案?

所以,因为我有 a_level 和 b_level(我所说的任何 b_level 都是只有一个 a_level 的“子级”),为拾取物品而创建的最有效的 SELECT 和 INDEX 是什么?

4

2 回答 2

1

您当然可以索引每一列。如果这样做,MySQL 将使用index merge优化将许多索引应用于单个查询。但是,为了提高效率,您可能希望使用复合索引(多列上的单个索引)。MySQL 复合索引用于优化,遵循左前缀规则。如果SELECT语句受索引左前缀中包含的术语的限制,则使用该索引。例如,如果您有

SELECT * FROM t WHERE a_level = 1 AND b_level = 2

那么适当的索引必须包含a_levelb_level作为第一列。换句话说,(a_level, b_level)可以索引查询的索引,例如

SELECT * FROM t WHERE a_level = 1
SELECT * FROM t WHERE a_level = 1 AND b_level = 2

但不是

SELECT * FROM t WHERE b_level = 2

因为b_level不是索引的左前缀。

您可能首先要对您最常执行的选择进行基准测试,并根据该选择创建索引,只要它们遵循左前缀规则即可。您可能希望对一些不同的SELECT查询使用多个索引,以免覆盖整个表。在不准确了解数据和查询的情况下,要完美回答这个问题并不容易。

但是,如果您确定您永远不会再次写入表中,那么如果空间不是问题,您不妨用索引覆盖整个内容。

于 2011-10-12T18:52:02.607 回答
0

如果您确实经常按一列或一组列进行选择,则索引该列或一组列。索引不会查看所有数百万个项目,这就是它们是索引的原因(没有索引,它确实会查看所有数百万个项目)

于 2011-10-12T18:35:32.960 回答