我有一个包含以下列的表:
id-> PK
customer_id-> index
store_id-> index
order_date-> index
last_modified-> index
other_columns...
other_columns...
我有三个单列索引。我还有一个customer_id_store_id索引,它是引用其他表的外键约束。
id,customer_id,store_id是char(36),它是UUID。 order_date是datetime,last_modifed是UNIX时间戳。
我希望通过删除所有索引并添加一个(customer_id,store_id,order_date)来获得一些性能。大多数查询都会在where子句中包含这些字段。但有时候不需要store_id。
最好的方法是什么?添加" store_id IS NOT NULL"在where子句中或以这种方式创建索引(customer_id,order_date,store_id)。
我还经常需要通过last_modified字段查询表(where子句包括customer_id =,store_id =,last_modified>)。
由于我只有一个列索引,并且有数百个客户插入/更新表,因此索引更多地扫描行超过必要的行。创建另一个索引(customer_id,store_id,last_modified)或保留原样是否更好?或者将此列添加到上一个索引,使其成为四列复合索引。但是,order_date在这里再次无关紧要,省略它可能会导致索引没有按预期使用。
该查询可以快速处理那些可能在那里使用customer_id索引的行不多的客户。但对于拥有大量数据的客户来说,这并不是最佳选择。更常见的是,我只需要几天的数据。
任何人都可以建议在这种情况下最佳指数是什么。
答案 0 :(得分:1)
MySQL表上的大量单列索引通常被认为是有害的。
使用
进行查询WHERE customer_id=constant AND store_id=constant AND last_modified>=constant
将由(customer_id, store_id, last_modified)
上的索引加速。为什么? MySQL查询计划程序可以随机访问索引到需要检索的第一个项目,然后按顺序扫描索引。该指数适用于
WHERE customer_id=constant AND store_id=constant
AND last_modified>=constant
AND last_modified< constant + INTERVAL 1 DAY
但是,该索引对于仅使用
的查询没有用处WHERE store_id=constant AND last_modified>constant
或
WHERE customer_id=constant AND store_id IS NOT NULL AND last_modified>=constant
对于第一个查询模式,您需要(store_id, last_modified)
才能实现顺序扫描索引。
这些查询模式中的第二个需要两个不同的范围搜索。一个是something IS NOT NULL
。这是一个范围搜索,因为它必须遍历列中的所有非空值。第二个范围搜索是last_modified>=constant
。这是一个范围搜索,因为它以满足给定标准的last_modified
的第一个值开始,并扫描到索引的末尾。
MySQL索引是B树。这实际上意味着他们将被分类为特定的单个订单。因此,索引最适合加速仅需要一个范围搜索的查询。因此,第二个查询模式本身很难用索引来满足。
一个表可以有多个复合索引,旨在满足多种不同的查询模式。通常,大表的策略在实际应用中运行良好。每个索引都会对更新和插入产生一点性能损失。索引也占用存储空间。但是这些天存储非常便宜。
如果要使用复合索引搜索多个条件,则必须满足以下条件:
store_id = constant
等平等标准。last_modified >= constant
或something IS NOT NULL
。http://use-the-index-luke.com/是黑色索引艺术的基础介绍。