Postgresql 多对多表-性能很差
下表列出:Postgresql 多对多表-性能很差,postgresql,indexing,many-to-many,postgresql-performance,Postgresql,Indexing,Many To Many,Postgresql Performance,下表列出: --- player -- id serial name VARCHAR(100) birthday DATE country VARCHAR(3) PRIMARY KEY id --- club --- id SERIAL name VARCHAR(100) country VARCHAR(3) PRIMARY KEY id --- playersinclubs --- id SERIAL player_id INTEGER (with INDEX) club_id INTEG
--- player --
id serial
name VARCHAR(100)
birthday DATE
country VARCHAR(3)
PRIMARY KEY id
--- club ---
id SERIAL
name VARCHAR(100)
country VARCHAR(3)
PRIMARY KEY id
--- playersinclubs ---
id SERIAL
player_id INTEGER (with INDEX)
club_id INTEGER (with INDEX)
joined DATE
left DATE
PRIMARY KEY id
每个玩家在表中都有一行玩家(带有他的属性)。同样地,每个俱乐部都有一个参加桌上俱乐部的项目。
对于球员职业生涯中的每一站,球员都会在table playersInClubs(n-m)中输入球员加入俱乐部的日期,也可以选择球员离开俱乐部的日期
我的主要问题是这些表的性能。在TablePlayer中,我们有超过1000万个条目。如果我想显示一个俱乐部的历史记录,其中所有球员都为该俱乐部效力,我的选择如下所示:
SELECT * FROM player
JOIN playersinclubs ON player.id = playersinclubs.player_id
JOIN club ON club.id = playersinclubs.club_id
WHERE club.dbid = 3;
但是对于大量的玩家,将在table player上执行序列扫描。这个选择需要很多时间
在我为我的应用程序实现一些新功能之前,每个玩家只有一个团队(只有今天的团队和玩家)。
所以我没有桌球运动员俱乐部。取而代之的是,我有一个乒乓球队员的球队id。我可以使用where子句team_id=3在table player中直接选择一个团队的球员
是否有人为我的数据库结构提供了一些性能提示来加速这些选择?表看起来不错,查询也不错。让我们看看查询应该做什么:
create unique index idx_playersinclubs on playersinclubs(club_id, player_id, joined);
这将是表的唯一业务密钥。我知道,在许多具有技术ID的数据库中,这些唯一的约束还没有建立,但我认为这是这些数据库中的缺陷,并且总是会创建这些约束/索引。
因此,可能只是上述索引还不存在。最重要的是,您需要
玩家俱乐部(俱乐部id,球员id)
上的索引。剩下的是细节(可能仍然会有很大的不同)。你需要准确地说出你的实际目标。你写道: 他的所有球员都为这家俱乐部效力: 您根本不需要加入
俱乐部
:
SELECT p.*
FROM playersinclubs pc
JOIN player p ON p.id = pc.player_id
WHERE pc.club_id = 3;
您也不需要在输出中使用列playersinclubs
,这对性能来说是一个小小的提升-除非它只允许对playersinclubs
进行索引扫描,否则它可能会很重要
player
列。仅选择实际需要的列
player
上的主键提供该表所需的索引
您需要在playersinclubs(俱乐部id,球员id)
上建立一个索引,但是not必须使其唯一,除非球员不允许再次加入同一俱乐部
如果玩家可以多次加入,而您只需要一个“所有玩家”列表,那么您还需要添加一个DISTINCT
步骤来折叠重复条目。你可以:
SELECT DISTINCT p.* ...
但是,由于您正在尝试优化性能:尽早消除重复比较便宜:
SELECT p.*
FROM (
SELECT DISTINCT player_id
FROM playersinclubs
WHERE club_id = 3;
) pc
JOIN player p ON p.id = pc.player_id;
也许您真的需要playersinclubs
中的所有条目以及表中的所有列。但你的描述不是这样的。查询和索引会有所不同
密切相关的回答:
解释(分析,详细)
生成的执行计划。请问,您是否还需要playersinclubs{player,date_joined+left}
上的日期范围限制?顺便说一句:你并不真的需要桥接表上的代理键。基本信息丢失了。考虑[ PostgreSQL性能]标签信息中的指令。那么你有答案吗?我添加了索引PrimeService俱乐部(CulbGyID,PraseRyId),但性能大致相同。也许没有办法提高这个数据表的性能?。。。