mysql subselect替代方案

时间:2009-09-30 06:04:46

标签: sql mysql optimization

让我们说我正在分析高中体育记录如何影响入学率。

所以我有一张桌子,每排对应一个高中篮球比赛。每个游戏都有一个客场球队ID和一个主队ID(FK到另一个“球队桌”)和主场得分,客场得分和日期。我正在写一个与本季篮球比赛的出席情况相匹配的查询。

我的示例输出将是(#_students_missed_classday_of_gamehome_teamaway_teamhome_team_wins_this_seasonaway_team_wins_this_season

我现在想要添加每个团队在上一季的分析方式。好吧,我将他们上一季的比赛存储在游戏桌中,但我应该可以通过一个子选择来实现。

因此,在我的主要选择语句中,我添加了子选择:

SELECT COUNT(*) FROM game_table
WHERE game_table.date
BETWEEN 'start of previous season' AND 'end of previous season'
AND (
  (game_table.home_team = team_table.id
    AND game_table.home_score > game_table.away_score)
  OR (game_table.away_team = team_table.id
    AND game_table.away_score > game_table.home_score))

在这种情况下,team-table.id指的是home_team的id,所以我现在拥有从前一年计算的所有胜利。

这种计算方法既不耗费时间也不耗费资源。 Explain SQL显示我在Type字段中有ALL,而我没有使用Key,查询超时。我不确定如何使用subselect完成更高效的查询。写下4个问题(主场胜利,主场失利,客场胜利,客场失利)似乎效率低下。

我相信这可能更清晰。如果有人有疑问,我明天会绝对添加颜色

2 个答案:

答案 0 :(得分:0)

在我看来,这是“试图让我的rdbms为我做的一切”的另一个案例。您必须接受无法针对某些场景/查询优化数据库,并且无论您添加多少索引,子查询等内容都会减慢较大的父查询。

上面的示例就是一个明显的例子:您从子查询中显示的数据(上一季中团队的表现)是静态数据 - 它是历史数据,不会/不会发生变化。您应该单独查询这些数据,将其保存在应用程序的内存中,并在循环时将其手动添加到主查询的结果中。

答案 1 :(得分:0)

您在MySQL中的最佳选择是拥有一个可以根据需要加入的视图。

如果MySQL支持CTE,那么您可以在一个语句中完成所有操作......

with prior_season as (
  select ...
)
  select
     ...
  join prior_season as hone_wins on ...
  join prior_season as home_losses on ...
  ... etc

如果你想要做很多事情,那么转换到不同的RDBMS可能是一个不错的理由。 Postgres现在支持它们,几乎所有主要商业供应商的免费版本也都支持它们。