Вот моя система:
Linux Ubuntu 18.04 LTS
MySQL 5.7
У меня есть запрос (ниже), выполнение которого занимает слишком много времени.
Это занимает столько времени, сколько 9 секунд. Это ненадежное количество времени для пользователя, ожидающего завершения загрузки веб-страницы.
Кроме того, набор данных большой и расширяется. Таблица событий имеет 250 000 строк. Я обычно добавляю от 1200 до 1800 строк в день.
Чтобы помочь в оптимизации, я хотел бы добавить индексы и тому подобное, но я не уверен, как (и если) я могу сделать это с помощью производного / объединенного выбора. запрос у меня есть.
Вот мой запрос. (Кто-нибудь знает, как ограничить ширину вывода, чтобы нам не приходилось прокручивать вправо, чтобы увидеть полную строку?)
mysql> explain select OUTSIDE.ownerUID as Owner,
OUTSIDE.propUID as Property,
OUTSIDE.camname as 'Camera Name',
OUTSIDE.direction as Direction,
OUTSIDE.camtimestamp as 'Event Time',
convert_tz(now(),'UTC','US/Central') as Now,
sec_to_time(convert_tz(now(),'UTC','US/Central') - OUTSIDE.CamTimeStamp) as 'Elapsed Time'
from events OUTSIDE,
(select camname,max(camtimestamp) as maxtimestamp from events group by camname) as INSIDE
where OUTSIDE.camname = INSIDE.camname
AND OUTSIDE.camtimestamp = INSIDE.maxtimestamp;
+----+-------------+------------+------------+-------+----------------------+--------------+---------+---------------------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+-------+----------------------+--------------+---------+---------------------+--------+----------+-------------+
| 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 263103 | 100.00 | Using where |
| 1 | PRIMARY | OUTSIDE | NULL | ref | camtimestamp,camname | camtimestamp | 6 | INSIDE.maxtimestamp | 1 | 99.73 | Using where |
| 2 | DERIVED | events | NULL | index | camname | camname | 257 | NULL | 263103 | 100.00 | NULL |
+----+-------------+------------+------------+-------+----------------------+--------------+---------+---------------------+--------+----------+-------------+
3 rows in set, 1 warning (0.03 sec)
Вот результаты запроса:
mysql> select OUTSIDE.ownerUID as Owner,
OUTSIDE.propUID as Property,
OUTSIDE.camname as 'Camera Name',
OUTSIDE.direction as Direction,
OUTSIDE.camtimestamp as 'Event Time',
convert_tz(now(),'UTC','US/Central') as Now,
sec_to_time(convert_tz(now(),'UTC','US/Central') - OUTSIDE.CamTimeStamp) as 'Elapsed Time'
from events OUTSIDE,
(select camname,max(camtimestamp) as maxtimestamp from events group by camname) as INSIDE
where OUTSIDE.camname = INSIDE.camname
AND OUTSIDE.camtimestamp = INSIDE.maxtimestamp;
+-------+----------+-------------+-----------+---------------------+---------------------+--------------+
| Owner | Property | Camera Name | Direction | Event Time | Now | Elapsed Time |
+-------+----------+-------------+-----------+---------------------+---------------------+--------------+
| 1 | 1 | wls1 | In | 2020-01-30 12:27:31 | 2020-01-30 12:29:53 | 00:03:42 |
| 1 | 1 | wls2 | Out | 2020-01-30 12:25:29 | 2020-01-30 12:29:53 | 00:07:04 |
+-------+----------+-------------+-----------+---------------------+---------------------+--------------+
2 rows in set (6.49 sec)
================================================= ============== Спасибо всем, кто ответил на вопрос или прокомментировал. Я принял предложение Ууэрдо о составном индексе и получил следующие результаты:
mysql> create index CamNameCamTime on events (camname,camtimestamp);
mysql> select OUTSIDE.ownerUID as Owner,
OUTSIDE.propUID as Property,
OUTSIDE.camname as 'Camera Name',
OUTSIDE.direction as Direction,
OUTSIDE.camtimestamp as 'Event Time',
convert_tz(now(),'UTC','US/Central') as Now,
sec_to_time(convert_tz(now(),'UTC','US/Central') - OUTSIDE.CamTimeStamp) as 'Elapsed Time'
from events OUTSIDE,
(select camname,max(camtimestamp) as maxtimestamp
from events group by camname) as INSIDE
where OUTSIDE.camname = INSIDE.camname AND OUTSIDE.camtimestamp = INSIDE.maxtimestamp;
+-------+----------+-------------+-----------+---------------------+---------------------+--------------+
| Owner | Property | Camera Name | Direction | Event Time | Now | Elapsed Time |
+-------+----------+-------------+-----------+---------------------+---------------------+--------------+
| 1 | 1 | wls1 | In | 2020-01-30 18:43:19 | 2020-01-30 18:44:33 | 00:01:54 |
| 1 | 1 | wls2 | Out | 2020-01-30 18:41:51 | 2020-01-30 18:44:33 | 00:04:42 |
+-------+----------+-------------+-----------+---------------------+---------------------+--------------+
2 rows in set (0.00 sec)
mysql> explain select OUTSIDE.ownerUID as Owner,
-> OUTSIDE.propUID as Property,
-> OUTSIDE.camname as 'Camera Name',
-> OUTSIDE.direction as Direction,
-> OUTSIDE.camtimestamp as 'Event Time',
-> convert_tz(now(),'UTC','US/Central') as Now,
-> sec_to_time(convert_tz(now(),'UTC','US/Central') - OUTSIDE.CamTimeStamp) as 'Elapsed Time'
-> from events OUTSIDE,
-> (select camname,max(camtimestamp) as maxtimestamp
-> from events group by camname) as INSIDE
-> where OUTSIDE.camname = INSIDE.camname AND OUTSIDE.camtimestamp = INSIDE.maxtimestamp;
+----+-------------+------------+------------+-------+-------------------------------------+----------------+---------+------------------------------------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+-------+-------------------------------------+----------------+---------+------------------------------------+------+----------+--------------------------+
| 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 2 | 100.00 | Using where |
| 1 | PRIMARY | OUTSIDE | NULL | ref | camtimestamp,camname,CamNameCamTime | CamNameCamTime | 263 | INSIDE.camname,INSIDE.maxtimestamp | 1 | 100.00 | NULL |
| 2 | DERIVED | events | NULL | range | camname,CamNameCamTime | CamNameCamTime | 257 | NULL | 2 | 100.00 | Using index for group-by |
+----+-------------+------------+------------+-------+-------------------------------------+----------------+---------+------------------------------------+------+----------+--------------------------+
3 rows in set, 1 warning (0.00 sec)
Успех!