Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Можно ли 3 запроса выполнить за 1 раз? 
V
    Опции темы
Coder
Дата 2.6.2008, 07:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



Есть 2 таблицы: 
№1 - основная - содержит все пришедшие пакеты;
№2 - вспомогательная - содержит только самый свежий пакет от каждого пользователя. 

Такое разделение сделано, чтобы при запросе последнего сообщения не лопатить основную таблицу, а сразу выдавать последние данные.

Сейчас запись нового пакета в БД осуществляется через 4 запроса:
1. Проверить, чтобы пришедшее время в пакете было больше чем время в таблице №2 от этого пользователя.
2. Если пакет свежее, из таблицы №2 удалить запись и вставить новую.
3. Записать пакет в таблицу №1.

Возможно ли объединить в одном запросе к БД действия пунктов 1 и 2? И как, если возможно?

PM MAIL   Вверх
FINANSIST
Дата 2.6.2008, 08:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Статус: Жив
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 11.4.2008
Где: Москва

Репутация: нет
Всего: 23



 smile 
1)Блин, ну ты даёшь - на фига такой геморой с таблицами. Такое решение задачи неприемлемо с точки зрения проектирования БД. Храни всё в одном пакете , ты вложенными запросами можешь сформировать любой селект с любыми  критериями отбора, и не париться делая из 1 таблицы 2 .
2) Можешь за раз делать хоть сто запросов нажатием 1 кнопки на форме, только делай это програмно, через VBA 
Код


DoCMD.RunSQL("select.......................................;")
DoCMD.RunSQLRunSQL("select.......................................;")
DoCMD.RunSQLRunSQL("select.......................................;")


Это сообщение отредактировал(а) FINANSIST - 2.6.2008, 08:11


--------------------
“...Брали корову рыжую одну, отдавать будем корову рыжую одну, чтобы не нарушать отчетности”
Эдуард Успенский, “Каникулы в Простоквашино”
PM MAIL ICQ   Вверх
Coder
Дата 2.6.2008, 08:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



А если в основной таблице уже более 2000000 записей и это число быстро растет? И программу пишу я на Си с использованием MySQL API. Мне приходится 4 раза обращаться к БД, а хотелось бы 2.
PM MAIL   Вверх
Coder
Дата 2.6.2008, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



Приложение серверное, работать должно быстро.
PM MAIL   Вверх
FINANSIST
Дата 2.6.2008, 08:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Статус: Жив
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 11.4.2008
Где: Москва

Репутация: нет
Всего: 23



SORRY! Не посмотрел что тема -  MYSQL , все равно (ИМХО) решение деления одной таблицы на две ( с одинаковой структурой) только для ускорения выборки довольно странно. 
Вопрос изначально стоит именно в этом, а не в выполнении цепочки последовательных запросов.
Я иногда дублирую таблицы - но это операция необходима для формировния временных срезов с дополнительной вставкой туда вычислений начальных, конечных сальдо, маржинальных доходов и прочих прелестей, (с последующим формированием из этого массива куба и очищением этой второй таблицы )но это вызванная необходимость. А зачем применять это в данном случае, не особо понятно.


--------------------
“...Брали корову рыжую одну, отдавать будем корову рыжую одну, чтобы не нарушать отчетности”
Эдуард Успенский, “Каникулы в Простоквашино”
PM MAIL ICQ   Вверх
Coder
Дата 2.6.2008, 08:54 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



FINANSIST, смотри:
Пользователь запрашивает - "дай мне последнюю информацию от ТОГО пользователя".
Я, по коду пользователя, сообщение которого ищут, выдергиваю из таблицы №2 данные. Притом простейшим запросом - select * from table1 where (user_ud=3). Все! А табличка в которой миллионы записей лишний раз не перебирается, тем более что искать в ней самое свежее сообщение прийдется по полю ДатаВремя.
PM MAIL   Вверх
Feldmarschall
Дата 2.6.2008, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
****


Профиль
Группа: Участник
Сообщений: 2641
Регистрация: 11.12.2007

Репутация: 3
Всего: 32



Цитата(Coder @  2.6.2008,  08:54 Найти цитируемый пост)
скать в ней самое свежее сообщение прийдется по полю ДатаВремя. 

Для этого в БД придуманы индексы.
или постой. ты правда выбираешь все записи пользователя, чтобы потом самостоятельно найти среди них одну нужную?

Цитата(Coder @  2.6.2008,  07:40 Найти цитируемый пост)
Возможно ли объединить в одном запросе к БД действия пунктов 1 и 2?

А зачем?
PM   Вверх
FINANSIST
Дата 2.6.2008, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Статус: Жив
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 11.4.2008
Где: Москва

Репутация: нет
Всего: 23




Если действительно в основной таблице "миллионы" записей и запрос последних , самых актуальных пакетов приходится делать очень часто, то реализованный подход кажется эффективным, однако если придется сделать иную выборку, то от сложных вложенных запросов тебе всё равно не уйти .

Цитата

SORRY! Не посмотрел что тема -  MYSQL 

Принципиально не говорю о том, чего не знаю или в чём не уверен ( очень полезная в жизни превычка). 
Придётся соблюсти её и в даннос случае.

Будут вопросы по ACCESS,EXCEL, VBA - обращайся! 


--------------------
“...Брали корову рыжую одну, отдавать будем корову рыжую одну, чтобы не нарушать отчетности”
Эдуард Успенский, “Каникулы в Простоквашино”
PM MAIL ICQ   Вверх
Coder
Дата 2.6.2008, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



Feldmarschall, если поиск последних данных делать по сразу по таблице №1, то сначала выбираю все сообщения от нужного пользователя, а потом среди них ищу максимальную дату - так сейчас работает.
Индексы есть, но нужно еще быстрее.

Цитата(Feldmarschall @  2.6.2008,  17:03 Найти цитируемый пост)
А зачем?

Затем чтобы при написании кода в Си 1 раз сформировать буфер с текстом запроса к БД и передать его функции mysql_query() на выполнение.

Цитата(FINANSIST @  2.6.2008,  17:14 Найти цитируемый пост)
Будут вопросы по ACCESS,EXCEL, VBA - обращайся! 

Ок. Спасибо!

Добавлено @ 10:03
Вот Запросы и условия их выполнения, которые мне нужно запихнуть в 1 запрос к БД:

Код

if ( (select count(*) from last_data where('2008-06-01 20-11-05'>date_time and user_id=7)) <>0 ) then
    begin
        delete from last_data where (user_id=7);
        insert into last_data values(....);
    end;


Можно ли реализовать такую условную ветку на MySQL?

Это сообщение отредактировал(а) Coder - 2.6.2008, 10:04
PM MAIL   Вверх
Feldmarschall
Дата 2.6.2008, 12:10 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
****


Профиль
Группа: Участник
Сообщений: 2641
Регистрация: 11.12.2007

Репутация: 3
Всего: 32



Цитата(Coder @  2.6.2008,  09:53 Найти цитируемый пост)
Индексы есть, но нужно еще быстрее.

Извини, я не очень понял это предложение. Нужно ещё быстрее, чем что?

Цитата(Coder @  2.6.2008,  09:53 Найти цитируемый пост)
Затем чтобы при написании кода в Си 1 раз сформировать буфер с текстом запроса

а зачем?

Цитата(Coder @  2.6.2008,  09:53 Найти цитируемый пост)
потом среди них ищу максимальную дату - так сейчас работает.

не пробовал сразу получить из БД нужную строку?
PM   Вверх
Coder
Дата 2.6.2008, 12:48 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



Feldmarschall, МНЕ ТАК НУЖНО. Что зачем, что не пробывал? Много, что пробывал, для своей задачи я выбрал такой путь решения. Я не понял зачем эта вся писанина? Грубо говоря, я спрашиваю, можно ли вот это: 
Код

if ( (select count(*) from last_data where('2008-06-01 20-11-05'>date_time and user_id=7)) <>0 ) then
        delete from last_data where (user_id=7);
insert into last_data values(....);

"запихать" в один запрос на языке SQL для СУБД mysql. 

Это сообщение отредактировал(а) Coder - 2.6.2008, 12:54
PM MAIL   Вверх
Feldmarschall
Дата 2.6.2008, 12:53 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
****


Профиль
Группа: Участник
Сообщений: 2641
Регистрация: 11.12.2007

Репутация: 3
Всего: 32



Затем, что если ты сам не озаботился найти смысл в своих действиях, то подсказать тебе это. Я задал тебе просте вопросы, на которые несложно ответить. И отделить осмысленные действия от бессмысленных. 
Грубо говоря, так никто не делает. А если ты такой оригинальный, то не надо у других спрашивать, как сделать через нетрадиционное место. 

Цитата(Coder @  2.6.2008,  12:48 Найти цитируемый пост)
Много что пробовал

Молодец. Однако пробы должны подкрепляться минимальными теоретическими познаниями. В частности - умением работать с бд. Отсутствие которого ты наглядно демонстрируешь. В результате твой вопрос превращается в детский каприз. 

PM   Вверх
skyboy
Дата 2.6.2008, 12:54 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(Coder @  2.6.2008,  11:48 Найти цитируемый пост)
Грубо говоря, я спрашиваю, можно ли вот это: if ( (select count(*) from last_data where('2008-06-01 20-11-05'>date_time and user_id=7)) <>0 ) then    begin        delete from last_data where (user_id=7);        insert into last_data values(....);    end; "запихать" в один запрос на языке SQL для СУБД mysql. 

нет. в один нельзя. а теперь, может, давай поищем другие пути?

PM MAIL   Вверх
Coder
Дата 2.6.2008, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



Цитата(Feldmarschall @  2.6.2008,  20:53 Найти цитируемый пост)
Затем, что если ты сам не озаботился найти смысл в своих действиях, то подсказать тебе это.

Я не против подсказки и хорошего совета, но все же хотелось услышать ответ на вопрос.

skyboy, спасибо, теперь я знаю что так сделать нельзя.  И можно поискать другие пути решения.

В таблице следующие поля:
id, user_id, date_time, message, param1, param2, ..., paramN

Как вытащить последние данные для конкретного пользователя?


Feldmarschall, таблица проиндексирована по полям id, user_id, date_time.
PM MAIL   Вверх
Feldmarschall
Дата 2.6.2008, 13:54 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
****


Профиль
Группа: Участник
Сообщений: 2641
Регистрация: 11.12.2007

Репутация: 3
Всего: 32



другие искать надо не потому, что кривым нельзя, а потому что он - кривой. 
чем не устраивает запрос order by date_time desc limit 1?

Это сообщение отредактировал(а) Feldmarschall - 2.6.2008, 13:55
PM   Вверх
Coder
Дата 2.6.2008, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



Код

select * from _info where (user_id=2) order by date_time desc limit 1;

У меня в локальной копии БД 1`965`603 записей, такой запрос в среднем выполняется за 1 секунду. Рабочий комп - Pentium M 1.6, 1Gb.

Сервер конечно мощнее, но и данных там больше.
PM MAIL   Вверх
Akina
Дата 2.6.2008, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 106
Всего: 454



Цитата(Coder @  2.6.2008,  15:03 Найти цитируемый пост)
У меня в локальной копии БД 1`965`603 записей, такой запрос в среднем выполняется за 1 секунду

Это говорит об отсутствии индекса. Или об использовании неправильного индекса.
давай начнем с цитирования структуры таблицы, включая индексы, и explain-а вот этого распоследнего запроса.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Feldmarschall
Дата 2.6.2008, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
****


Профиль
Группа: Участник
Сообщений: 2641
Регистрация: 11.12.2007

Репутация: 3
Всего: 32



возможно, может понадобиться составной индекс user_id, date_time

Если в консоли выполнить запрос EXPLAIN select * from _info where (user_id=2) order by date_time desc limit 1; - что выведет?
PM   Вверх
Coder
Дата 2.6.2008, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



Akina
Код

CREATE TABLE _info (
    id    INT UNSIGNED NOT NULL AUTO_INCREMENT,
    user_id    INT UNSIGNED NOT NULL,
    date_time    DATETIME NOT NULL,
    param1    DOUBLE NOT NULL,
    param2    DOUBLE NOT NULL,
    param3    FLOAT NOT NULL,
    param4    INT    UNSIGNED NOT NULL,
    PRIMARY KEY (id),
    KEY (user_id),
    KEY (date_time)
) ENGINE=MyISAM DEFAULT CHARACTER SET 'cp1251'; 


Код

explain select * from _info where (user_id=1) order by date_time desc limit 1;

выдает:
Код

| id | select_type | table    | type | possible_keys | key    | key_len | ref   | rows   | Extra
|  1 | SIMPLE      | gps_info | ref  | user_id       | user_id| 4       | const | 177026 | Using where; Using filesort


PM MAIL   Вверх
Feldmarschall
Дата 2.6.2008, 22:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
****


Профиль
Группа: Участник
Сообщений: 2641
Регистрация: 11.12.2007

Репутация: 3
Всего: 32



попробуй сделать 
Код

create index u_date on _info (user_id,date_time);

оно уберет filesort и должно стать быстрее.
PM   Вверх
Coder
Дата 3.6.2008, 02:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



Feldmarschall, и правда! Теперь время выполнения такой выборки = 0.00. И колонка Extra показывает, что используется только where.

Мне только не понятно, почему не был создан индекс при создании базы данных? Я же явно указал -  KEY (date_time). Или тут дело именно в составном индексе?


Feldmarschall,  +1

Это сообщение отредактировал(а) Coder - 3.6.2008, 02:37
PM MAIL   Вверх
skyboy
Дата 3.6.2008, 03:20 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(Coder @  3.6.2008,  01:35 Найти цитируемый пост)
тут дело именно в составном индексе

два индекса использоваться не могут, а у тебя ведь условие по одному и сортировка по другому.
потому составной ключ решил проблему. 
а ещё, так как where выполняется до сортировки, то порядок следования полей в объявлении индекса должен быть именно таким.
PM MAIL   Вверх
Feldmarschall
Дата 3.6.2008, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
****


Профиль
Группа: Участник
Сообщений: 2641
Регистрация: 11.12.2007

Репутация: 3
Всего: 32



Coder, насколько я себе это представляю.
индекс - это файл, который, грубо говоря, состоит из пар "значение поля - позиция в файле", отсортированный по значению поля. 
Поиск по отсортированному списку происходит на порядки быстрее.
В случае с одиночным индексом он используется, но помогает выбрать только строки одного юзера - а их 17 тысяч. А их уже приходится сортировать заново - ведь индекс по дате здесь не получится использовать - он тоже по всему файлу строится, и без информации о юзере.
А составной индекс отсортирован по двум полям, то есть, имеет вид
1, 2001
1, 2002
1, 2003
2, 2001
2, 2005
5, 2008

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

PM   Вверх
Coder
Дата 4.6.2008, 04:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



Feldmarschall, доходчиво.

Помечаю вопрос ка решенный.
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0700 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.