powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Создание сложного запроса к большой таблице
29 сообщений из 29, показаны все 2 страниц
Создание сложного запроса к большой таблице
    #38708782
Leonid_Polenov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Проблема следующая: имеется таблица примерно с 1млн записей. Каждый день в таблицу записывается около 30-400 записей. Необходимо через определенный промежуток времени (пару месяцев) удалять из таблицы записи с сохранением только одной на каждый день. Выборку по одной записи на каждый день сделал так:
Код: plsql
1.
2.
3.
select id FROM iis.current_32_54_1 
where datetime < '2014-06-01' 
group by date_format(DateTime, '%Y-%m-%d')



Выборку всех ненужных записей:
Код: plsql
1.
2.
3.
4.
select id from iis.current_32_54_1 
where id <> all (SELECT id FROM iis.current_32_54_1 
where datetime < '2014-06-01' 
group by date_format(DateTime, '%Y-%m-%d'))



А удаление планировал выполнить так:
Код: plsql
1.
2.
3.
4.
5.
delete from iis.current_32_54_1 
where id in (select id from (select id from iis.current_32_54_1 
where id <> all (SELECT id FROM iis.current_32_54_1 
where datetime < '2014-06-01' 
group by date_format(DateTime, '%Y-%m-%d'))) as g1);



Но в ответ MySQL надолго задумывается и ничего не возвращает. Изначально собирал запрос на тестовой маленькой таблице, так все проходило корректно. В таблице есть поля id, DateTime из несколько других с измерительной информацией. Работать нужно с полем DateTime.
Прошу помощи или подсказать, как можно иным способом почистить таблицу от избыточных записей.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38708790
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid_Polenov,

1)вместо IN-подзапросов переписываете через джойны
2)если будет ругаться, что не может удалить, поскольку таблица уже задействована в селекте, то вытаскиваете все идшники удаляемых записей во временную таблицу и удаляете их из основной отдельным запросом
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38708794
Leonid_Polenov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tanglir,

Ok! Сейчас попробую сделать по вашему совету...
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38708799
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirесли будет ругаться, что не может удалить, поскольку таблица уже задействована в селекте, то вытаскиваете все идшники удаляемых записей во временную таблицу и удаляете их из основной отдельным запросом
Лучше сделать вьюшку - нафига ему та таблица? лишняя нагрузка на диск и никаких профитов.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38708880
Leonid_Polenov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите, почему может помирать такой запрос:
Код: plsql
1.
2.
CREATE TEMPORARY table currTemp as select id, DateTime FROM iis.current_32_54_1 
where datetime < '2014-06-01' group by date_format(DateTime, '%Y-%m-%d');


При этом часть с SELECT без создания временной таблицы исполняется довольно быстро. Каким способом иначе можно выбрать по одной записи за каждый день?
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38708944
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мануалы читать не пробовали? CREATE TABLE ... SELECT не предусматривает TEMPORARY.
http://dev.mysql.com/doc/refman/5.6/en/create-table-select.html
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709068
Leonid_Polenov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
Возможно, что и упустил((( Извиняюсь. Но с таблицей меньшего размера данная конструкция проходит отлично и создается временная таблица. Создание временной таблицы с использованием Select'а из другой с условием приведено и в русскоязычной книжке MySQL 5 в подлиннике 2010.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709088
Users
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaМануалы читать не пробовали? CREATE TABLE ... SELECT не предусматривает TEMPORARY.
http://dev.mysql.com/doc/refman/5.6/en/create-table-select.html

Ээээ?
CREATE TEMPORARY TABLE test
SELECT 1;

Status: ok mysql 5.6.19
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709093
Users
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid_Polenov,

Коллега, а попробуйте так: вот у вас день новый начался, сделайте еще одно поле, запишите туда некий id.
Больше ничего в этот день не пишите, тогда у вас за весь день - только одна запись, остальные null, ага?

далее просто удаляете из таблицы все, где это поле null - и не заморачиваетесь с выборкой. Index на дату + это поле - максимум, что потребуется.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709110
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsersAkinaМануалы читать не пробовали? CREATE TABLE ... SELECT не предусматривает TEMPORARY.
http://dev.mysql.com/doc/refman/5.6/en/create-table-select.html

Ээээ?
CREATE TEMPORARY TABLE test
SELECT 1;

Status: ok mysql 5.6.19Что это было?
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709116
Users
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaUsersпропущено...


Ээээ?
CREATE TEMPORARY TABLE test
SELECT 1;

Status: ok mysql 5.6.19Что это было?

это был запрос с селектом, который создал TEMPORARY TABLE.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709132
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaМануалы читать не пробовали? CREATE TABLE ... SELECT не предусматривает TEMPORARY.
http://dev.mysql.com/doc/refman/5.6/en/create-table-select.html Тоже не соглашусь. http://dev.mysql.com/doc/refman/5.6/en/create-table.html CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(create_definition,...)]
[table_options]
[partition_options]
select_statement
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709248
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алё, народ... а по ссылке сходить не судьба?
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709251
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Usersэто был запрос с селектом, который создал TEMPORARY TABLE.Может, у меня плохо с арифметикой? я вижу ДВА запроса...
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709268
Users
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina,

Не ссорьтесь, горячие эстонские парни.

Вот оригинальный запрос.

CREATE TEMPORARY table currTemp as select id, DateTime FROM iis.current_32_54_1
-- where datetime < '2014-06-01' group by date_format(DateTime, '%Y-%m-%d');

Так вот, я кладу на наковальню, что он выполнится и таблицу currTemp создаст. А не создает ее только из-за условия where - которое я тут заремил. работает оно у топикстартера слишком долго и скорее всего, он этот запрос срубает.

Два тут запроса или один - не суть важно. Если же буквоедствовать -то select тут один. :-Р
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709309
Leonid_Polenov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем большое спасибо!
Решение найдено таким образом:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
START TRANSACTION;
  CREATE TEMPORARY TABLE CurrTemp SELECT * FROM iis.current_32_54_1 WHERE DateTime < '2014-07-01' group BY Date(DateTime);
  INSERT INTO CurrTemp SELECT * FROM iis.current_32_54_1 WHERE DateTime > '2014-07-01';
  TRUNCATE TABLE iis.current_32_54_1;
  INSERT INTO iis.current_32_54_1 SELECT * FROM CurrTemp;
  DROP TABLE CurrTemp;
COMMIT;


Все работает нормально, начальный запрос был рабочий, но видимо ресурсоемкий и по переменной Innodb_lock_wait_timeout блокировался. После этого БД не давала создать временные таблицы, но и это решилось только после рестарта mysql.
Изменил и условие в GROUP BY с приведением к переменной Date, в этом случае приведение как раз и подошло и ускорило исполнение с 1,6 сек до 0,5 сек.
Завернул в транзакцию, но возможно и не надо было?
Общее исполнение около 5 сек с 203тыс. записями вполне устраивает...


Еще раз большое спасибо!
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709384
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid_Polenov
Код: plsql
1.
SELECT * ... group BY Date(DateTime)

Уж сколько раз твердили миру...
Вам совершенно все равно, какая именно запись из целого дня попадет в итоговую таблицу?
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709499
Users
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid_Polenov,

Какое-то очень мудреное решение, имхо. Как минимум - три раза лопатим одну и ту же таблицу. Даже если там есть индекс - смысл по ней два раза проходиться? И переливать в нее то, что в ней и так было...
Что сейчас 5 секунд на таблицу из 200 тысяч записей - по моему, многовато.

Смотрите еще раз:

1 предложенный мной вариант - заводим еще одно поле. Пишем туда раз в день некий id, по нему и выбираем потом, какая именно запись из 20 тысяч за один день нужна. Делаем по полю индекс. Профит - выборка будет у вас очень быстрая. Удаление тоже. Никаких group by не нужно. Но будет масса дыр в identity поле и вообще смысл сначала писать в таблицу, а потом из нее массово удалять?

2 вариант: Вообще не трогаем эту вашу таблицу, а заводим новую, с такими же полями. Для совместной выборки делаем вьюху, обьединяющий старую и новую. В новую пишем данные за два месяца. в нужный момент перекидываете в старую - только те записи, которые выбираете сейчас группировкой - и так до следующего раза. Сюда же можно присовокупить идею из варианта 1.
Профит:

1 - лопатить будете меньшее число записей. Записи более ранние, за тот же 2013 год в выборке сейчас у вас участвуют, у меня - не будут.
2. ускорение выборки - по сути, это секционирование. Если известно, данные за какой период нужны - можно искать их всего в одной таблице из моих двух и это будет быстрей, чем в вашем случае с одной общей под все.

P.s. select * - это лоховство. Всегда пишите список и порядок полей в явном виде.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709545
Leonid_Polenov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

Мне нужна самая первая за день. В принципе так и происходит, изначально еще было в конце с order by но результат тот же.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709547
Leonid_Polenov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftLeonid_Polenov
Код: plsql
1.
SELECT * ... group BY Date(DateTime)

Уж сколько раз твердили миру...


Что имелось ввиду? Если полезный совет - рад очень буду услышать))
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709552
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid_Polenovmiksoftпропущено...
Уж сколько раз твердили миру...


Что имелось ввиду? Если полезный совет - рад очень буду услышать))При использовании в секции SELECT (и в любых других, которые исполняются после группировки) полей, которых нет в группировке приводит к тому, что для этих полей значения берутся из произвольной записи в пределах группы. И никак это изменить нельзя. По факту это обычно та запись, которая встретилась раньше в физическом порядке обработки.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709574
Leonid_Polenov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Users,

Вариант 1 действительно удобен, не знаю хорошо ли так реализовывать. Применить его не смогу, т.к. база существующая, не нормированная, воющем проблемная. Таких таблиц очень много для большого перчня устройств. И копаться в исходниках для применения варианта 1 и 2 очень трудоемко.

Было бы интересно придумать запрос в меньшее количество операций и шустрее, конечно же.

На счет select * все понятно, но в моем случае при работе с одной и той же таблицей не вижу нужды перечислять все столбцы. Если изменения коснуться этой таблицы - то для данных выражений проблем не будет...
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709582
Leonid_Polenov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

То есть, если в таблице есть определенное кол-во записей, группируемых по некоторому полю, то значение других полей могут быть от других записей в пределах конкретной группы?
Пример (абстрактный):
Val1,Val2
1,2
1,7
2,1
2,4
Группируя по Val1 могу получить результат:
1, 7
2, 1 ?
Если это так, то это повод изменять запрос
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709583
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid_PolenovНа счет select * все понятно, но в моем случае при работе с одной и той же таблицей не вижу нужды перечислять все столбцы.Мы тоже так когда-то думали... пока не натолкнулись на внезапно изменившийся порядок полей.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709586
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid_PolenovПример (абстрактный):
Val1,Val2
1,2
1,7
2,1
2,4
Группируя по Val1 могу получить результат:
1, 7
2, 1 ?Да, можете.
Причем удаление/вставка записей может это изменить. Применение другого индекса это может изменить. Изменение запроса, например, добавлением JOIN-а с другой таблицей это может изменить.
Leonid_PolenovЕсли это так, то это повод изменять запросТут целый FAQ на эту тему есть.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709663
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaАлё, народ... а по ссылке сходить не судьба?Офф: сходил, явного запрета не увидел. Дай цитату, из которой это следует.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38709901
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirAkinaАлё, народ... а по ссылке сходить не судьба?Офф: сходил, явного запрета не увидел. Дай цитату, из которой это следует.Ну забыли на той страничке слово [TEMPORARY] подрисовать, бывает. Главное, что на базовой страничке не забыли. Насколько помню, на форуме это уже обсуждали пару лет назад.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38712183
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid_PolenovВсем большое спасибо!
Решение найдено таким образом:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
START TRANSACTION;
  CREATE TEMPORARY TABLE CurrTemp SELECT * FROM iis.current_32_54_1 WHERE DateTime < '2014-07-01' group BY Date(DateTime);
  INSERT INTO CurrTemp SELECT * FROM iis.current_32_54_1 WHERE DateTime > '2014-07-01';
  TRUNCATE TABLE iis.current_32_54_1;
  INSERT INTO iis.current_32_54_1 SELECT * FROM CurrTemp;
  DROP TABLE CurrTemp;
COMMIT;


Все работает нормально, начальный запрос был рабочий, но видимо ресурсоемкий и по переменной Innodb_lock_wait_timeout блокировался. После этого БД не давала создать временные таблицы, но и это решилось только после рестарта mysql.
Изменил и условие в GROUP BY с приведением к переменной Date, в этом случае приведение как раз и подошло и ускорило исполнение с 1,6 сек до 0,5 сек.
Завернул в транзакцию, но возможно и не надо было?
Общее исполнение около 5 сек с 203тыс. записями вполне устраивает...


Еще раз большое спасибо!

и что оно работает?

666

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

насколько я понимаю транкейт закроет транкзанкцию твою, в это время вставяться новый записи которые ты нужны. ты их накроеш медным тазом, и будешь думать что оно работает, а оно почти работает.
...
Рейтинг: 0 / 0
Создание сложного запроса к большой таблице
    #38712187
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,

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


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