powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите сделать запрос лучше
8 сообщений из 8, страница 1 из 1
Помогите сделать запрос лучше
    #39981135
vinn.consult
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет! Помогите с запросом.. Нужно вытащить object_id до указанного времени (timestamp), а если есть новее, то выводить не нужно. Не могу сформировать запрос..точнее получилось, но работает он отвратительно (0.64 sec) на таблице в 300к записей (индексы шаманил).

Сама таблица:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
MySQL [db]> SELECT * FROM db.object_data WHERE object_id = '33282' LIMIT 10;
+-----+-----------+---------------------+
| id  | object_id | timestamp           |
+-----+-----------+---------------------+
| 140 |     33282 | 2020-07-16 20:12:12 |
| 146 |     33282 | 2020-07-16 20:12:13 |
| 201 |     33282 | 2020-07-16 20:12:22 |
| 221 |     33282 | 2020-07-16 20:12:26 |
| 333 |     33282 | 2020-07-16 20:12:52 |
| 336 |     33282 | 2020-07-16 20:12:52 |
| 364 |     33282 | 2020-07-16 20:12:58 |
| 472 |     33282 | 2020-07-16 20:13:21 |
| 473 |     33282 | 2020-07-16 20:13:21 |
| 485 |     33282 | 2020-07-16 20:13:22 |
+-----+-----------+---------------------+
10 rows in set (0.00 sec)



Что получилось сделать:
Код: sql
1.
2.
SELECT DISTINCT object_id FROM db.object_data WHERE object_id IN (SELECT object_id FROM db.object_data WHERE timestamp < (NOW() - INTERVAL 12 HOUR))
		AND object_id NOT IN (SELECT object_id FROM db.object_data WHERE timestamp > (NOW() - INTERVAL 12 HOUR))



Уверен что можно по другому сделать, но не знаю что в этом случае применять нужно
...
Рейтинг: 0 / 0
Помогите сделать запрос лучше
    #39981143
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: sql
1.
2.
3.
4.
SELECT object_id
FROM db.object_data
GROUP BY object_id
HAVING MAX(timestamp) < NOW() - INTERVAL 12 HOUR
...
Рейтинг: 0 / 0
Помогите сделать запрос лучше
    #39981277
vinn.consult
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
paver,

Спасибо за ответ, запрос работает как надо! Но скорость... (1.10 sec). Добавлял индексы на object_id,timestamp, вместе, отдельно, менял местами их..или тут структура самой таблицы неправильная..?

Код: sql
1.
2.
3.
4.
5.
6.
7.
MySQL [(none)]> explain SELECT object_id FROM db.object_data GROUP BY object_id HAVING MAX(timestamp) < NOW() - INTERVAL 40 HOUR;
+----+-------------+-------------+------------+-------+---------------+-----------+---------+------+--------+----------+-------+
| id | select_type | table       | partitions | type  | possible_keys | key       | key_len | ref  | rows   | filtered | Extra |
+----+-------------+-------------+------------+-------+---------------+-----------+---------+------+--------+----------+-------+
|  1 | SIMPLE      | object_data | NULL       | index | object_id     | object_id | 8       | NULL | 551271 |   100.00 | NULL  |
+----+-------------+-------------+------------+-------+---------------+-----------+---------+------+--------+----------+-------+
1 row in set, 1 warning (0.00 sec)
...
Рейтинг: 0 / 0
Помогите сделать запрос лучше
    #39981292
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vinn.consult, как измеряете скорость? Через профайлинг?
...
Рейтинг: 0 / 0
Помогите сделать запрос лучше
    #39981297
vinn.consult
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
paver,

Смотрел вывод в терминале

Код: sql
1.
17644 rows in set (1.40 sec)



Такая маленькая таблица и так тормозит. Пытался добавить USE INDEX (object_id,timestamp) запрос стал выполняться за 0.34 sec против 1.40 sec без добавления. Может быть дело в FOREIGN KEY ? или уже все, предел ( ?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE TABLE `object_data` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `object_id` bigint(20) NOT NULL,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `object_id` (`object_id`),
  CONSTRAINT `object_data_ibfk_1` FOREIGN KEY (`object_id`) REFERENCES `object` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=604341 DEFAULT CHARSET=utf8
...
Рейтинг: 0 / 0
Помогите сделать запрос лучше
    #39981304
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vinn.consult, про оптимизации - это не ко мне, я сам чайник. Но
неплохо бы посмотреть скорость через show profiles;
http://yournet.kz/blog/mysql/kak-uznat-vremya-vypolneniya-mysql-zaprosa
https://dev.mysql.com/doc/refman/5.7/en/show-profile.html
Ну и смущает объем результирующей выборки. 17644 rows - оно вам зачем?
Попробуйте еще посмотреть скорость на инвертированной выборке, смените < на >. Как вообще скорость меняется в зависимости от размера результата.
...
Рейтинг: 0 / 0
Помогите сделать запрос лучше
    #39981307
vinn.consult
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Выполнил профилирование как указано по ссылке, видимо запрос работает нормально, просто данных много :) Они нужны для переноса в другую таблицу (это логика приложения такая). Оставлю все как есть. Спасибо за помощь!

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000184 |
| checking permissions | 0.000049 |
| Opening tables       | 0.000055 |
| init                 | 0.000085 |
| System lock          | 0.000047 |
| optimizing           | 0.000042 |
| statistics           | 0.000072 |
| preparing            | 0.000060 |
| Sorting result       | 0.000040 |
| executing            | 0.000037 |
| Sending data         | 0.367184 |
| end                  | 0.000061 |
| query end            | 0.000021 |
| closing tables       | 0.000019 |
| freeing items        | 0.000037 |
| cleaning up          | 0.000025 |
+----------------------+----------+
...
Рейтинг: 0 / 0
Помогите сделать запрос лучше
    #39981349
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуйте переписать на NOT EXISTS - должно быть не медленнее как минимум. Типа

Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT object_id
FROM object_data t1
WHERE timestamp < @timestamp
  AND NOT EXISTS ( SELECT NULL
                   FROM object_data t2
                   WHERE t1.object_id = t2.object_id
                     AND t1.timestamp < t2.timestamp )



@timestamp - заданный порог времени.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите сделать запрос лучше
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]