如何索引此表(a_level,b_level,item_id)

时间:2011-10-12 18:32:48

标签: mysql indexing database-indexes

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

假设我们有数百万件物品,所有物品都被插入一次,然后只需要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 =上都是INDEX,那会不好?我猜只有b_level上的INDEX和item_id以及SELECT WHERE b_level = AND item_id =才足够/最佳解决方案?

所以,既然我有a_level和b_level(我说的任何b_level只是一个a_level的“child”),那么为拾取项目创建的最有效的SELECT和INDEX是什么?

2 个答案:

答案 0 :(得分:1)

您当然可以索引每一列。如果这样做,MySQL将使用index merge优化将多个索引应用于单个查询。但是,为了提高效率,您可能希望使用复合索引(多列上的单个索引)。通过遵循left-prefix rule,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查询使用多个索引,以防止覆盖整个表。在不完全了解数据和查询的情况下完美回答这个问题并不容易。

但是,如果您确定再也不会写入表格,那么如果空间不是问题,您可以用索引覆盖整个事物。

答案 1 :(得分:0)

如果您经常按列或一组列进行选择,则索引该列或一组列。索引看起来并不是数百万个项目,这就是为什么它们是索引(没有索引,它确实会看到数百万个项目)