如何正确索引多个关联表?

Rus*_*uss 19 sql sql-server postgresql many-to-many query-optimization

在像这样的典型的许多安排......

Movies       Actors       Movies_Actors
------       ------       -------------
movie_ID     actor_ID     FK_movie_ID
title        name         FK_actor_ID

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

我通常只在关联表中使用复合主键来完成此操作,如下所示:

CREATE TABLE Movies_Actors (
  FK_movie_ID INTEGER,
  FK_actor_ID INTEGER,
  PRIMARY KEY (FK_movie_ID, FK_actor_ID)
)
Run Code Online (Sandbox Code Playgroud)

然而,这似乎是指数搜索时才有用处 movie_IDactor_ID(虽然我不是一个综合指数是否也适用于各个列确定).

由于两个"什么演员在电影X"和"有演员Ÿ一直处于什么样的电影"将是此表的通用查询,似乎应该对每一列单独的索引快速找到自己的角色和电影.复合索引是否有效地做到了这一点?如果没有,那么在这张桌子上使用复合索引似乎毫无意义.如果复合索引毫无意义,那么如何处理主键呢?候选键显然是两列的组合,但是如果得到的复合索引是无意义的(它一定不是?),这似乎是浪费.

此外,这个环节增加了一些困惑,并表示,它甚至可能是真正有用的指定2个综合指数...他们为一体(FK_movie_ID, FK_actor_ID),另一个反向的(FK_actor_ID, FK_movie_ID),与选择哪种是主键(因而通常聚集并且'只是'一个独特的复合索引,基于更多的查询方向.

什么是真实的故事?复合索引是否自动有效地索引每列以便在一个或另一个上进行搜索?应的最佳(在读出速度,而不是尺寸)关联表具有在每个方向上的复合指数每列一个?什么是幕后机制?


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

Mar*_*and 13

(虽然我不确定复合索引是否也适用于各列).

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

此外,这个链接增加了一些混淆,并表明实际指定两个复合索引甚至可能是有用的...其中一个为(FK_movie_ID,FK_actor_ID),另一个反向为(FK_actor_ID,FK_movie_ID),

这实际上是要做的事情.

将一个作为聚类索引,另一个作为非聚类索引,无论如何都将包含聚类索引键 - 因此不需要再次包含该列(thx到JNK).

CREATE CLUSTERING INDEX a on Movies_Actors (fk_movie_id, fk_actor_id);
CREATE NONCLUSTERING INDEX b on Movies_Actors (fk_actor_id);
Run Code Online (Sandbox Code Playgroud)

什么是真实的故事?

http://Use-The-Index-Luke.com/ :)

复合索引是否自动有效地索引每列以便在一个或另一个上进行搜索?

不.只有索引的前缀.如果你有索引(a,b,c),查询a =?和b =?可以使用索引.但是c =?不能,也不能b =?和c =?.

最佳(读取速度,不是大小)关联表是否在每个方向上都有一个复合索引,每列上有一个?

如果你需要加入两个方向,是("每个方向的复合索引")和否("每列一个").

什么是幕后机制?

嗯,再次相同的链接.

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

  • @Russ,Markus - 在两列上设置覆盖索引,顺序颠倒,浪费空间.在'A,B`上有一个索引,在`B`上有一个等价于在`A,B`上有一个,在'B,A`上有一个,除了你不需要额外的索引空间和相应的更新/插入如果您只索引第二个索引中的一列.如果他们选择两个列,它将使用覆盖索引,无论顺序如何. (2认同)