MySQL самый быстрый способ получить максимальное значение под конкретным порогом - PullRequest
0 голосов
/ 05 мая 2011

У меня есть две таблицы и медленный запрос в MySQL.

Таблицы:

  1. Таблица клипов с полями channel, start_time, end_time

  2. Таблица показывает с полями channel, start_time,end_time

в обеих таблицах есть индексы для поля start_time.

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

Пока у меня есть этот запрос:

SELECT (
   SELECT shows.id 
   FROM shows
   WHERE shows.starttime<=clips.starttime AND shows.channel=clips.channel
   ORDER BY shows.starttime DESC
   LIMIT 1) as show_id,
   clips.*
FROM clips

Для небольшого количества клипов это прекрасно работает, но для большого количества клипов это становится слишком медленным.

Насколько я понимаю, чтоЗависимый подзапрос должен быть очень быстрым, поскольку для start_time существует индекс, и все, что нужно сделать, - это поиск по индексу.Тем не менее, он медленный и объясняет состояние запроса «используя где» вместо «используя индекс».

Вот вывод команды объяснения

--+------------------+-----+-----+------------+---------+------+----+------+-----------------------+
id| select_type      |table|type |possibleKeys| key     |keylen|ref |rows  | Extra                 |
--+------------------+-----+-----+------------+---------+------+----+------+-----------------------+
 1|PRIMARY           |clips|range| startDate  |startDate| 8    |NULL| 9095 |Using where;Using index|
 2|DEPENDENT SUBQUERY|shows|index| startDate  |startDate| 8    |NULL|287896|Using where;Using index|
--+------------------+-----+-----+------------+---------+------+----+------+-----------------------+

Будем весьма благодарны за любые предложения по улучшению производительности для этой задачи.

Ответы [ 2 ]

0 голосов
/ 05 мая 2011

Я думаю, что добавление индекса, который использует столбцы start_time и channel, может повысить производительность запроса до приемлемого значения.

Ответ Йохана великолепен, но, учитывая ваши фильтры, я думаю, что индекс может улучшитьсяпроизводительность в любом случае.

0 голосов
/ 05 мая 2011

Попробуйте переписать запрос как

SELECT max(shows.starttime) as show_start, shows.id as show_id, clips.*
FROM shows
INNER JOIN clips ON (clips.channel = shows.channel AND shows.starttime<=clips.starttime)
GROUP BY clips.id

Поскольку клипы являются частью шоу, вы можете ожидать, что они будут близко друг к другу, вы можете ограничить количество показов, выполнив что-то вроде:

SELECT max(shows.starttime) as show_start, shows.id as show_id, clips.*
FROM shows
INNER JOIN clips ON (clips.channel = shows.channel 
  AND clips.starttime BETWEEN shows.starttime AND DATE_ADD(shows.starttime, INTERVAL 1 DAY) )
GROUP BY clips.id

Это предотвратит выполнение MySQL полного подзапроса с сортировкой в ​​каждой строке клипов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...