我是SQL代码的新手,我只选择几列并使用大多数GROUP BY
函数,但我的代码需要2分钟才能显示结果可能不是很长的查询,但我需要更快。如何更快地进行SQL查询?
对于我的代码,我有一个联赛匹配的表格;
实施例
CustomerID MatchDate League Matches HomeTeam AwayTeam
------------------------------------------------------------------------------------------------------------------------
1 11-12-2006 La Liga Barcelone-R.Madrid Barcelona RealMadrid
2 10-10-2006 Premier League Everton-Arsenal Everton Arsenal
3 09-10-2006 Premier League Arsenal-Tottenham Barcelona RealMadrid
4 10-10-2006 Bundesliga Bayern-Mainz Bayern MainZ
我的目标是,计算每个比赛的总ID,以便HomeTeam和AwayTeam为联盟和球队和季节找到每个球队和小组的总观察数。 同样的团队可以是HomeTeam和AwayTeam,所以我使用了这段代码。
SELECT League, SUM(totalnum), Teams, Season FROM
(
(SELECT DATE_FORMAT(MatchDate, '%Y') as 'Season', HomeTeam as Teams, League, count(distinct CustomerID) as "totalnum"
FROM MY_TABLE GROUP BY League, Teams, Season )
UNION ALL
(SELECT DATE_FORMAT(MatchDate, '%Y') as 'Season', AwayTeam as Teams, League, count(distinct CustomerID) as "totalnum"
FROM MY_TABLE GROUP BY League, Teams, Season )
) aa
GROUP BY League, Teams, Season
ORDER BY totalnum DESC
我可以得到结果,但我需要更短。哪些点可能会影响我的查询。
答案 0 :(得分:2)
如果你应用这两个索引,我希望你现有的查询应该加快......
CREATE INDEX MY_TABLE_league_home_date_cust
ON MY_TABLE(
League, HomeTeam, MatchDate, CustomerID
);
CREATE INDEX MY_TABLE_league_away_date_cust
ON MY_TABLE(
League, AwayTeam, MatchDate, CustomerID
);
尽管如此,我怀疑您的查询所涉及的最高费用是COUNT(DISTINCT CustomerID)
。这样做涉及必须对所有数据进行排序。这个可能意味着以下索引可能更好......
CREATE INDEX MY_TABLE_cust_league_home_date
ON MY_TABLE(
CustomerID, League, HomeTeam, MatchDate
);
CREATE INDEX MY_TABLE_cust_league_away_date
ON MY_TABLE(
CustomerID, League, AwayTeam, MatchDate
);
另一个观察结果是,在您的查询中,您COUNT()
独特的"家庭客户"然后COUNT()
独特的"客户",然后SUM()
他们。这意味着任何去过主场比赛和客场比赛的人都会计算两次。那是为了吗?
如果不是这样,您可能会发现查询的费用更高......
SELECT
Team,
League,
DATE_FORMAT(MatchDate, '%Y') AS Season,
COUNT(DISTINCT CustomerID) AS total
FROM
(
SELECT CustomerID, League, HomeTeam AS Team, MatchDate FROM MyTable
UNION ALL
SELECT CustomerID, League, AwayTeam AS Team, MatchDate FROM MyTable
)
combined_view
GROUP BY
Team, League, Season
ORDER BY
total DESC
我认为你最好的选择是为Season
添加一个计算列,然后使用第一个索引的略微修改版本......
ALTER TABLE
MY_TABLE
ADD Season VARCHAR(4) AS (
DATE_FORMAT(MatchDate, '%Y')
);
CREATE INDEX MY_TABLE_league_home_season_cust
ON MY_TABLE(
League, HomeTeam, Season, CustomerID
);
CREATE INDEX MY_TABLE_league_away_season_cust
ON MY_TABLE(
League, AwayTeam, Season, CustomerID
);
SELECT
Team,
League,
Season,
COUNT(DISTINCT CustomerID) AS total
FROM
(
SELECT CustomerID, League, HomeTeam AS Team, Season FROM MyTable
UNION ALL
SELECT CustomerID, League, AwayTeam AS Team, Season FROM MyTable
)
combined_view
GROUP BY
Team, League, Season
ORDER BY
total DESC
答案 1 :(得分:1)
你能试试吗?
SELECT DATE_FORMAT(A.MatchDate, '%Y') as 'Season',
case c.col
when 'home' then A.HomeTeam
when 'away' then A.AwayTeam
end as Teams,
A.League, count(distinct A.CustomerID) as "totalnum"
FROM MY_TABLE A
cross join ( select 'home' as col union all select 'away') c
GROUP BY League, Teams, Season
ORDER BY totalnum DESC
在SQL Fiddle中查看结果:new:http://sqlfiddle.com/#!9/dd0335/11(上一个:http://sqlfiddle.com/#!9/dd0335/9)