【发布时间】:2014-08-18 23:38:07
【问题描述】:
请看一下这个 SELECT 语句:
SELECT
b.player_id,
COUNT(CASE WHEN a.team = m.team_win THEN 1 END),
COUNT(CASE WHEN a.team <> m.team_win THEN 1 END)
FROM
players a,
players b,
JOIN
matches m
ON m.match_id = b.match_id
WHERE
a.player_id <> b.player_id
and a.team <> b.team
and a.player_id = 100
GROUP BY
b.player_id
完成后,该语句应显示一个记录集,其列是:
-
a.player_id对阵的b.player_id。 -
count的比赛中a.player_id击败了b.player_id。 -
a.player_id被b.player_id击败的比赛中的count。
不幸的是,这些表相当大。 matches 大约有 160 万行。 players 大约有 1700 万行,因此加入它们会带来一些挑战:
执行计划索引查找players 和matches 两个表,然后发出nested loop (inner join),这是一个估计有1,176,730,000,000 行的步骤。
其他杂项。资料:
player_id 是 tinyint,team 是 bit,team_win 是 bit。
match_id 是 bigint primary key,在 players 上有一个外键约束
匹配表
CREATE TABLE [dbo].[Matches](
[match_id] [bigint] NOT NULL,
[match_seq_id] [bigint] NOT NULL,
[team_win] [bit] NOT NULL,
CONSTRAINT [PK_Matches] PRIMARY KEY CLUSTERED (
[match_id] ASC
) ON [PRIMARY]
) ON [PRIMARY]
玩家表
CREATE TABLE [dbo].[Players] (
[id] [int] PRIMARY KEY IDENTITY NOT NULL,
[match_id] [bigint] NOT NULL,
[account_id] [bigint] NOT NULL,
[team] [bit] NOT NULL,
[player_id] [tinyint] NOT NULL,
/* column list has been truncated for brevity. */
CONSTRAINT [PK_Players] PRIMARY KEY CLUSTERED (
[id] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Players] ADD CONSTRAINT [FK_Players_Matches] FOREIGN KEY([match_id])
REFERENCES [dbo].[Matches] ([match_id])
【问题讨论】:
-
您的查询没有按照您的想法执行。请提供
players和matches表的布局。例如,为什么名为players的表中会有matchid? -
你有一个笛卡尔积...在玩家 b 上加入玩家 a,其中 a.playerID b.playerID 正在创建 1700 万 - 1 * 1700 万 - 1 行....可以'不是故意的,可以吗?
-
@GordonLinoff:添加了表格。将球员想象成,更像是“参加特定比赛的球员”。 Matches 中的每个
match_id大约有 10 个,给予或接受。 -
@Twelfth:这是我想得到我想要的结果集的唯一方法。如果有更好的方法(我很肯定肯定有),那么我需要学习它。
-
抱歉,请向 gordon 阅读上述评论。所以这应该是每个玩家的赢/输数?
标签: sql sql-server performance database-performance