Я очень новичок в кодах 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
Моя цель: подсчитать общий идентификатор для каждого матча, дать для 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
Я могу получить результат, но мне нужно меньше. Какие точки могут повлиять на мой запрос.
Если вы примените эти два индекса, я ожидаю, что ваш существующий запрос ускорится...
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
Можете ли вы попробовать это?
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)
SUM(COUNT(DISTINCT)+COUNT(DISTINCT))
достаточно? Если ваш достаточно, это более простая оценка разумно; просто удалитьDISTINCT
? Что важнее, точность или время выполнения? Вам необходимо четко изучить свои требования и формулировку проблемы, нередко требование основывается на том, что это будет легко, но после осознания того, что это сложно / медленно / дорого, выдвигается более простое требование.