小编典典

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

sql

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

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)
)

但是,似乎索引仅在 同时 搜索movie_ID和时才有用actor_ID(尽管我不确定复合索引是否也适用于各个列)。

由于“该影片X中的演员是什么”和“该演员Y所处的电影是什么”都是该表的常见查询,因此似乎在每列上都应该有一个单独的索引,以快速地独立定位演员和电影。
。复合索引是否可以有效地做到这一点?如果没有,则在此表上拥有复合索引似乎毫无意义。如果复合索引毫无意义,那么对主键怎么办?候选键显然是两列的组合,但是如果组合索引的结果毫无意义(一定不是吗?),那似乎是一种浪费。

此外,此链接还增加了一些混乱,并表明实际上指定 两个
复合索引可能甚至有用。其中一个为(FK_movie_ID, FK_actor_ID),另一个为(FK_actor_ID, FK_movie_ID),选择为主键(因此通常是聚簇的) ),这是“唯一”的唯一综合索引,该索引基于要查询的方向更多。

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


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


阅读 217

收藏
2021-04-15

共1个答案

小编典典

(尽管我不确定复合索引是否也适用于各个列)。

是的,它可以。但只有前缀: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 CLUSTERED INDEX a on Movies_Actors (fk_movie_id, fk_actor_id);
CREATE NONCLUSTERED INDEX b on Movies_Actors (fk_actor_id);

真实的故事是什么?

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

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

否。仅索引的前缀。如果您有索引(a,b,c),则查询a =?和b =?可以使用索引。但是c =?不能,b =也不能?和c =?。

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

如果您需要双向连接,请选择是(“每个方向上的复合索引”),而不选择否(“每个列上的一个索引”)。

什么是幕后机制?

好吧,再次相同的链接。

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

2021-04-15