将多个索引添加到多态表的最佳方法是什么?

时间:2013-10-21 11:17:43

标签: mysql sql indexing

让我说我有类似于

的多态性
| document_id | owner_type | owner_id |
| 1           | Client     | 1        |
| 1           | Client     | 2        |
| 2           | User       | 1        |

我知道我会调用查询owner_typeowner_type + owner_id

SELECT * FROM document_name_ownerships WHERE owner_type = 'Client`
SELECT * FROM document_name_ownerships WHERE owner_type = 'Client` and owner_id = 1

让我们忽略如何索引document_id 我想知道为这个SQL场景索引所有者列的最佳方法(性能)

解决方案1:

CREATE INDEX do_type_id_ix ON document_ownerships (owner_type, owner_id)

这样我只有一个适用于两种情况的索引

解决方案2:

CREATE INDEX do_id_type_ix ON document_ownerships (owner_id, owner_type)
CREATE INDEX do_type_ix ON document_ownerships (owner_type)

这样我会有完全匹配数据库使用方式的索引。唯一的事情是,当我只有一个

时,我有2个索引

解决方案3:

CREATE INDEX do_id_ix ON document_ownerships (owner_id)
CREATE INDEX do_type_ix ON document_ownerships (owner_type)

单个列索引


从我在MySQL控制台中使用explain探索的内容我得到了非常相似的结果,因为它是一个新项目,我没有提供数据来正确地探索这个,所以我会100%肯定(甚至当我用数百条记录填充数据库时)。那么有人可以根据他们的经验给我一些建议吗?

1 个答案:

答案 0 :(得分:2)

这很大程度上取决于数据的分布 - 索引只有在good selectivity in the indexed columns时才有意义。

e.g。如果owner_type只有两个可能的值,即ClientUser,并且假设它们均匀分布,那么仅owner_type上的任何索引都将毫无意义。在这种情况下,像

这样的查询
SELECT * FROM document_name_ownerships WHERE owner_type = 'Client`;

可能会返回表中大部分记录,并且扫描是最好的(虽然我假设您的真实查询将加入派生表并过滤派生的特定于表的列,这将是与此非常不同的查询计划。)

因此我会考虑编制索引

  1. 仅在owner_id上,假设这本身就具有良好的选择性,
  2. 或者,仅在有证据表明索引#1不具有选择性时,才在组合(owner_id, owner_type)上,如果两个字段的组合提供足够的选择性以保证索引,则组合{{1}}。