powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Вытащить самые свежие значения
9 сообщений из 9, страница 1 из 1
Вытащить самые свежие значения
    #39494109
Алекс М.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Друзья, здравствуйте. Возможно, я малость перегрелся и задам тупой вопрос. Но...

Вот таблица, в которую валится статистика по неким источникам. Есть источник, который раз в N минут отдаёт некий результат. (Столбец src_id - внешний ключ.)

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE TABLE `stat` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `src_id` smallint(6) unsigned NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `result` smallint(2) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `src_id` (`src_id`)
) ENGINE=InnoDB AUTO_INCREMENT=732670 DEFAULT CHARSET=utf8


Соответственно, содержимое этой таблицы выглядит примерно так.
idsrc_iddateresult............73156712017-07-24 17:04:06073157322017-07-24 17:04:06173156632017-07-24 17:04:06073156842017-07-24 17:04:06073175032017-07-24 17:08:05073175242017-07-24 17:08:05273175112017-07-24 17:08:05073175322017-07-24 17:08:05073193432017-07-24 17:12:05073193542017-07-24 17:12:05073193712017-07-24 17:12:06073193622017-07-24 17:12:06273211812017-07-24 17:16:06073212222017-07-24 17:16:06073211932017-07-24 17:16:06073212742017-07-24 17:16:06073230232017-07-24 17:20:05073230322017-07-24 17:20:05073230512017-07-24 17:20:06173230442017-07-24 17:20:06073248632017-07-24 17:24:05073248742017-07-24 17:24:05073248912017-07-24 17:24:06073249122017-07-24 17:24:061............
А теперь собственно тупой вопрос. Как просто и без проктологии выцепить самые свежие значения result по всем src_id?
...
Рейтинг: 0 / 0
Вытащить самые свежие значения
    #39494129
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алекс М.Друзья, здравствуйте. Возможно, я малость перегрелся и задам тупой вопрос. Но...

Вот таблица, в которую валится статистика по неким источникам. Есть источник, который раз в N минут отдаёт некий результат. (Столбец src_id - внешний ключ.)

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE TABLE `stat` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `src_id` smallint(6) unsigned NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `result` smallint(2) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `src_id` (`src_id`)
) ENGINE=InnoDB AUTO_INCREMENT=732670 DEFAULT CHARSET=utf8



Соответственно, содержимое этой таблицы выглядит примерно так.
idsrc_iddateresult............73156712017-07-24 17:04:06073157322017-07-24 17:04:06173156632017-07-24 17:04:06073156842017-07-24 17:04:06073175032017-07-24 17:08:05073175242017-07-24 17:08:05273175112017-07-24 17:08:05073175322017-07-24 17:08:05073193432017-07-24 17:12:05073193542017-07-24 17:12:05073193712017-07-24 17:12:06073193622017-07-24 17:12:06273211812017-07-24 17:16:06073212222017-07-24 17:16:06073211932017-07-24 17:16:06073212742017-07-24 17:16:06073230232017-07-24 17:20:05073230322017-07-24 17:20:05073230512017-07-24 17:20:06173230442017-07-24 17:20:06073248632017-07-24 17:24:05073248742017-07-24 17:24:05073248912017-07-24 17:24:06073249122017-07-24 17:24:061............
А теперь собственно тупой вопрос. Как просто и без проктологии выцепить самые свежие значения result по всем src_id?


Код: sql
1.
2.
3.
4.
5.
6.
select *
from stat s1
left join stat s2
on s2.id > s1.id
and s2.src_id = s1.src_id 
where s2.id is null



index stat(src_id, id) (...или stat(src_id) достаточно....)
...
Рейтинг: 0 / 0
Вытащить самые свежие значения
    #39496581
Алекс М.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сделал указанный индекс. Однако помогло не сильно... В таблице около миллиона записей сейчас. В итоге упомянутый селект отработал за довольно продолжительное время:

Код: plaintext
188 rows in set (1 hour 5 min 25.14 sec)

На всякий случай:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
explain select * from `stat` s1 left join `stat` s2 on s2.id > s1.id and s2.src_id = s1.src_id  where s2.id is null;
+----+-------------+-------+------+--------------------------+--------+---------+----------------------+--------+-------------------------+
| id | select_type | table | type | possible_keys            | key    | key_len | ref                  | rows   | Extra                   |
+----+-------------+-------+------+--------------------------+--------+---------+----------------------+--------+-------------------------+
|  1 | SIMPLE      | s1    | ALL  | NULL                     | NULL   | NULL    | NULL                 | 963498 | NULL                    |
|  1 | SIMPLE      | s2    | ref  | PRIMARY,src_id,id_src_id | src_id | 2       | simple_mon.s1.src_id |   2474 | Using where; Not exists |
+----+-------------+-------+------+--------------------------+--------+---------+----------------------+--------+-------------------------+
2 rows in set (0.00 sec)
...
Рейтинг: 0 / 0
Вытащить самые свежие значения
    #39496588
Алекс М.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не это ли?

Код: sql
1.
SELECT src_id, MAX(date), result FROM `stat` GROUP BY src_id
...
Рейтинг: 0 / 0
Вытащить самые свежие значения
    #39496592
Алекс М.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нет, получилась хрень...
...
Рейтинг: 0 / 0
Вытащить самые свежие значения
    #39496595
Jude
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алекс М.Не это ли?

Код: sql
1.
SELECT src_id, MAX(date), result FROM `stat` GROUP BY src_id


нет. result будет не от MAX(date).
...
Рейтинг: 0 / 0
Вытащить самые свежие значения
    #39496609
Алекс М.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем, забил я на это дело и пошёл другим путём. Создал специальную табличку для самых свежих значений и перекладываю их туда триггером.
...
Рейтинг: 0 / 0
Вытащить самые свежие значения
    #39496835
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алекс М.В общем, забил я на это дело и пошёл другим путём. Создал специальную табличку для самых свежих значений и перекладываю их туда триггером.

1. для скорости чтения отдельная таблица свежих значений --
однозначно лучший вариант. Цена -- создание тригера
незначительные задержки на вставке.
Если вы сделали так и довольны -- отлично.

На будушее -- есть несколько вариантов которые можно
попробовать без отдельной таблицы:

2. Создайте индекс на ДВА поля (src_id, id), это может резко ускорить
первуй запрос и также полезно для вариантов ниже

3. у вас низкая кардиналити -- мало груп (188) и много
значений в группе (по 2500 в каждой групе).
В предложеном решении внутри каждой групы делается картезиан.
Это решение хорошо для высокой кардиналати но в данном случае получилось медлено.

Алтернативное решение для низкой кардиналити:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select s1.*
from 
(
select max(s2.id) max_id
from stat s2
group by s2.src_id
) s3
STRAIGHT_JOIN
stat s1
on s3.max_id = s1.id



..не забудем создать индекс STAT(src_id, id)

4. есть еще одно решение -- на переменных, но
оно относительно сложнее и не доказано что быстрее.
...
Рейтинг: 0 / 0
Вытащить самые свежие значения
    #39496839
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javajdbc,

....да, заметил что вы уже сделали двойной индекс...
но он не сработал на ">" (судя по EXPLAIN)...
для второго решения он должен сработать...я так думаю...
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Вытащить самые свежие значения
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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