关于sql:如何正确索引多对多关联表?

How to properly index a many-many association table?

在一个典型的许多这样的安排中…

1
2
3
4
Movies       Actors       Movies_Actors
------       ------       -------------
movie_ID     actor_ID     FK_movie_ID
title        name         FK_actor_ID

…如何索引关联表('Movies_Actors'以获得最佳读取速度?

我通常只在关联表中看到复合主键的情况下这样做,比如:

1
2
3
4
5
CREATE TABLE Movies_Actors (
  FK_movie_ID INTEGER,
  FK_actor_ID INTEGER,
  PRIMARY KEY (FK_movie_ID, FK_actor_ID)
)

但是,似乎只有在搜索movie_IDactor_ID时,索引才有用(尽管我不确定复合索引是否也适用于单个列)。

由于"电影X中的演员"和"电影Y中的演员"都是此表的常见查询,因此似乎每个列上都应该有一个单独的索引,以便快速定位演员和电影。复合索引是否有效地做到了这一点?如果没有,那么在这个表中使用复合索引似乎没有意义。如果一个复合索引是无意义的,那么如何处理主键呢?候选键显然是两列的组合,但如果生成的组合索引是无意义的(不能是?)这似乎是浪费。

此外,这个链接还增加了一些混淆,并指出实际指定两个复合索引甚至可能有用…其中一个作为(FK_movie_ID, FK_actor_ID),另一个作为(FK_actor_ID, FK_movie_ID),选择哪个是主键(因此通常是聚集的),这是一个唯一的复合索引,基于哪个方向查询更多。

真实的故事是什么?复合索引是否自动有效地为每列编制索引,以便在其中一列进行搜索?最佳(以读取速度,而不是以大小)关联表是否应该在每个方向和每个列上都有一个复合索引?什么是幕后机械师?

编辑:我发现这个相关的问题,出于某种原因,我在发布前找不到…如何在MySQL中正确索引多对多连接的链接表?


(although I'm not certain on whether a
composite index also works for the
individual columns).

是的,可以。但是只有前缀:http://use-the-index-luke.com/sql/where-clause/the-equals-operator/concatenated-keys

Also, this link adds some confusion
and indicates that it might even be
useful to actually specify two
composite indices... one of them as
(FK_movie_ID, FK_actor_ID), and the
other in reverse as (FK_actor_ID,
FK_movie_ID),

这就是要做的事。

一个作为集群索引,另一个作为非集群索引,无论如何都将包含集群索引键——因此不需要再次包含该列(thx到jnk)。

1
2
CREATE CLUSTERING INDEX a ON Movies_Actors (fk_movie_id, fk_actor_id);
CREATE NONCLUSTERING INDEX b ON Movies_Actors (fk_actor_id);

What is the real story?

http://use-the-index-luke.com/:)

Does a composite index automatically
effectively index each column for
searching on one or the other?

不,只有索引的前缀。如果您有一个索引(A、B、C),那么查询A=?B=?可以使用索引。但是C=?不能,也不能b=?C=?.

Should the optimal (in read speed, not
size) association table have a
composite index in each direction and
one on each column?

如果您需要在两个方向上连接,则选择"是"("每个方向的复合索引")和"否"("每个列上一个")。

What are the behind-the-scene mechanics?

嗯,又是同一个链接。

说到SQL Server,您可能最终也会考虑使用索引视图。这是一种预加入。如上所述,两个指数也可能足够快。


在SQL Server中,复合索引只能用于第一列的单个字段搜索。这意味着,如果在同一个查询中搜索该字段时不使用FK_Movie_id,那么您应该在FK_actor_id上增加一个字段索引。