2016-09-30 2 views
-1

Мой код запросов MySQL нравится, как показано ниже, и в таблице содержится около нескольких тысяч записей, теперь ниже SQL выполняется около 5 минут и более. Я ищу способы оптимизировать его, чтобы потребовалось меньше времени для выполнения. Спасибо!Как оптимизировать несколько таблиц MySQL, выбирают запросы?

SELECT `m`.`id`, 
    `m`.`id`, 
    `tr`.`name`, 
    `m`.`m_date`, 
    `t1`.`t_name` AS home, 
    `t2`.`t_name` AS away, 
    `m`.`score1`, 
    `m`.`score2`, 
    `cw1`.`tid` AS tid1, 
    `cw2`.`tid` AS tid2, 
    `o1`.`odds` AS odds1, 
    `o2`.`odds` AS odds2, 
    `m`.`m_time` 
FROM `jos_bl_match` AS `m` 
LEFT JOIN `jos_bl_matchday` AS `md` ON (`md`.`id` = `m`.`m_id`) 
LEFT JOIN `jos_bl_seasons` AS `s` ON (`s`.`s_id` = `md`.`s_id`) 
LEFT JOIN `jos_bl_tournament` AS `tr` ON (`tr`.`id` = `s`.`t_id`) 
LEFT JOIN `jos_bl_teams` AS `t1` ON (`m`.`team1_id` = `t1`.`id`) 
LEFT JOIN `jos_bl_teams` AS `t2` ON (`m`.`team2_id` = `t2`.`id`) 
LEFT JOIN `jos_vuvuzelaodds_odds` AS `o1` ON (`o1`.`m_id` = `m`.`id`) 
AND `o1`.`market_id` = 1 
AND `o1`.`bookmaker_id` = 1 
LEFT JOIN `jos_vuvuzelaodds_odds` AS `o2` ON (`o2`.`m_id` = `m`.`id`) 
AND `o2`.`market_id` = 1 
AND `o2`.`bookmaker_id` = 2 
LEFT JOIN `jos_cwtags_tags` AS `cw1` ON (`cw1`.`item_id` = `o1`.`m_id`) 
LEFT JOIN `jos_cwtags_tags` AS `cw2` ON (`cw2`.`item_id` = `o2`.`m_id`) 
WHERE `m`.`published` = 1 
AND `s`.`published` = '1' 
AND `tr`.`published` = '1' 
AND `s`.`s_id` = 869 
AND `m`.`m_played` = '1' 
AND `m`.`m_date` > 2013-01-01 
AND `o1`.`odds` != '' 
AND `o2`.`odds` != '' 
AND `cw1`.`cat_id` = 19 
AND `cw2`.`cat_id` = 21 
ORDER BY `m`.`m_date`, 
    `md`.`id`, 
    `s`.`s_id`, 
    `tr`.`id` DESC LIMIT 0, 15 

ответ

-1

Не имея доступа к базе данных, немного сложно сказать. Кажется, что много данных, чтобы вытащить только 15 записей. Вы уверены, что вам нужно вытащить данные таким образом?

Вероятно лучший маршрут:

  • Оптимизация базы данных, как показано ниже.
  • Сделайте плоский просмотр базы данных обо всех играх, у которых есть поля, которые вам нужны. Статическая таблица будет намного быстрее, но вам нужно будет настроить обновления с помощью триггеров, которые выходят за рамки этого ответа, но этот процесс аналогичен
  • Напишите запросы к представлению .

Вы не выбираете поля из таблицы сезонов в своем выборе. Я использовал поле из таблицы jos_bl_matchday.

Это должно вас начать. Вы можете также использовать условные в ваших избранных заявлениях

(IF value = 1, table.field, null) as yadda 

вместо присоединения одной таблицы снова и снова, но вы должны экспериментировать.

CREATE VIEW allTheGames AS SELECT 
`m`.`id` as id, 
`md`.`s_id` as seasonId, 
    `tr`.`name` as name, 
`m`.`m_date` as m_date, 
`t1`.`t_name` AS home, 
`t2`.`t_name` AS away, 
`m`.`score1` as score1, 
`m`.`score2` as score2, 
`cw1`.`tid` AS tid1, 
`cw2`.`tid` AS tid2, 
`o1`.`odds` AS odds1, 
`o2`.`odds` AS odds2, 
`m`.`m_time` as m_time 
      FROM `jos_bl_match` AS `m` 
      LEFT JOIN `jos_bl_matchday` AS `md` ON (`md`.`id` = `m`.`m_id`) 
      LEFT JOIN `jos_bl_tournament` AS `tr` ON (`tr`.`id` = `s`.`t_id`) 
      LEFT JOIN `jos_bl_teams` AS `t1` ON (`m`.`team1_id` = `t1`.`id`) 
      LEFT JOIN `jos_bl_teams` AS `t2` ON (`m`.`team2_id` = `t2`.`id`) 
      LEFT JOIN `jos_vuvuzelaodds_odds` AS `o1` ON (`o1`.`m_id` = `m`.`id`) AND `o1`.`market_id` = 1 AND `o1`.`bookmaker_id` = 1 
      LEFT JOIN `jos_vuvuzelaodds_odds` AS `o2` ON (`o2`.`m_id` = `m`.`id`) AND `o2`.`market_id` = 1 AND `o2`.`bookmaker_id` = 2 
      LEFT JOIN `jos_cwtags_tags` AS `cw1` ON (`cw1`.`item_id` = `o1`.`m_id`) 
      LEFT JOIN `jos_cwtags_tags` AS `cw2` ON (`cw2`.`item_id` = `o2`.`m_id`) 
      WHERE `m`.`published` = 1 AND `s`.`published` = '1' AND `tr`.`published` = '1' 
      AND `m`.`m_played` = '1' 
      AND `o1`.`odds1` != '' AND `o2`.`odds2` != '' 

Затем к нему запросу:

select * from allTheGames 
    WHERE season_id = 869 AND m_date > 2013-01-01 AND tid1 = 19 AND tid2 = 21 

шагов для оптимизации:

Выяснить, какие именно данные вы хотите из этого запроса и почему: Является ли это пользовательский отчет? Веб-страница? вам нужно иметь все эти данные сразу или было бы разумнее, если бы пользователь развернулся? Как часто выполняется запрос? Раз в минуту? Один раз в день? Сколько записей в каждой таблице? Ваше мнение должно отражать эту "игру" объект

База данных:

  • Run "объяснить" против этого запроса http://dev.mysql.com/doc/refman/5.7/en/explain.html.
  • Он покажет всю работу, выполняемую базой данных, план выполнения запросов и количество записей, которые он ищет. Обычно это происходит быстро: он фактически не выполняет запрос.
  • Смотрите, если вы можете поместить базу данных на SSD-дисках или даже RAM

Ваша структура таблицы:

  • Убедитесь, что у вас есть индексы на всех полях, которые вы ищете на. Есть много способов оптимизировать это.
  • Используйте «объяснять», чтобы MySQL мог использовать индексы.
  • Если в таблице jos_vuvuzelaodds_odds действительно есть только 2 рынка, рассмотрите возможность создания 2 полей.

Удачи вам!

1

«Нормализовать, но не перенастраивать».

Некоторые составные индексы, вы можете быть отсутствующие ...

jos_bl_match: INDEX(m_played, published, m_date) 

Колонки должны быть в таком порядке. Это позволит быстрее начать фильтрацию.

Следующая должно ускорить их соединения:

jos_vuvuzelaodds_odds: INDEX(market_id, bookmaker_id, m_id) 
jos_cwtags_tags: INDEX(cat_id, item_id) 

Похоже, эти два последних индексов может (должно) быть PRIMARY KEY. Они?

Некоторые (возможно, все) LEFT JOINs также могут быть INNER JOINs; Вы считали это?

Просьба указать EXPLAIN SELECT.

Смежные вопросы