У меня есть таблица со схемой вроде, скажем,
EventTime DATETIME(6),
EventType VARCHAR(20),
Number1 INT,
Number2 INT,
Number3 INT,
...
В этой таблице невообразимо большое количество строк, но ради этого запроса меня интересует, скажем,, несколько тысяч из них, которые находятся между двумя заданными значениями EventTime
.На EventTime
есть индекс, и если я просто сделаю что-то вроде
SELECT * FROM table WHERE EventTime >= time1 and EventTime <= time2;
, тогда он сможет вернуть соответствующие строки почти мгновенно.
Из строк в этом временном окнеЯ хочу извлечь именно те, где Number1
является наибольшим для любой строки с этим EventType
.Другими словами, я хочу сделать что-то эквивалентное этому запросу:
SELECT * FROM
(SELECT EventType, MAX(Number1) as max_Number1
FROM table
WHERE EventTime >= time1 AND EventTime <= time2
GROUP BY EventType) AS a
LEFT JOIN
(SELECT * FROM table
WHERE EventTime >= time1 AND EventTime <= time2) AS b
ON a.EventType = b.EventType AND a.max_Number1 = b.Number1)
Кажется, что он должен работать просто отлично - я могу запустить каждый из подзапросов, а именно:
SELECT EventType, MAX(Number1) as max_Number1
FROM table
WHERE EventTime >= time1 AND EventTime <= time2
GROUP BY EventType;
и
SELECT * FROM table
WHERE EventTime >= time1 AND EventTime <= time2;
практически мгновенно, поэтому на данный момент не должно быть слишком сложно получить желаемые результаты: база данных может отсортировать или проиндексировать результаты обоих подзапросов по EventType
, а затем просто сопоставитьвсе в порядке.
Однако, когда я на самом деле запускаю это, требуется навсегда .Я не знаю, как долго, потому что я никогда не позволял ему завершиться, но мне нужно больше времени, чем просто вручную получить результаты обоих запросов и выполнить объединение в другом месте.
Вопросы:
- Почему это занимает так много времени?Что делает движок базы данных?
- Есть ли способ написать этот запрос таким образом, чтобы он выполнялся разумно?
- Если нет, могу ли я написать его как хранимую процедурукаким-то образом?
Сложность: Поскольку в этой таблице десятки миллиардов строк, было бы очень дорого добавить к ней какие-либо дополнительные индексы.