Какие моменты ускоряют выполнение SQL-запросов

0

Я очень новичок в кодах 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

Я могу получить результат, но мне нужно меньше. Какие точки могут повлиять на мой запрос.

Теги:
query-performance

2 ответа

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

  • 0
    Почти то же время выполнения
  • 0
    Не могли бы вы показать план выполнения?
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню