假设我有类似于这个的多态性
| document_id | owner_type | owner_id |
| 1 | Client | 1 |
| 1 | Client | 2 |
| 2 | User | 1 |
我知道我会调用查询来寻找owner_type
和owner_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% 确定(即使我用几百条记录填充了 databese)。那么谁能从他们的经验中给我一些建议?
这在很大程度上取决于数据的分布 - 索引只有在索引列中具有良好的选择性时才有意义。
例如,如果owner_type
只有 2 个可能的值,即 Client
和 User
,并且假设它们是均匀分布的,那么任何仅在 owner_type
上的索引都将毫无意义。在这种情况下,像
SELECT * FROM document_name_ownerships WHERE owner_type = 'Client`;
可能会返回表中很大一部分记录,并且扫描是最好的(尽管我假设您的实际查询将联接到派生表并筛选派生表特定的列,这将是一个非常不同的查询计划与此
。因此,我会考虑索引
- 只有在
owner_id
上,假设这本身就给出了很好的选择性, - 或者,在组合
(owner_id, owner_type)
上,只有当有证据表明索引 #1 没有选择性时,并且如果 2 个字段的组合提供了足够的选择性来保证索引。