| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > MySQL > Можно ли 3 запроса выполнить за 1 раз? |
| Автор: Coder 2.6.2008, 07:40 |
| Есть 2 таблицы: №1 - основная - содержит все пришедшие пакеты; №2 - вспомогательная - содержит только самый свежий пакет от каждого пользователя. Такое разделение сделано, чтобы при запросе последнего сообщения не лопатить основную таблицу, а сразу выдавать последние данные. Сейчас запись нового пакета в БД осуществляется через 4 запроса: 1. Проверить, чтобы пришедшее время в пакете было больше чем время в таблице №2 от этого пользователя. 2. Если пакет свежее, из таблицы №2 удалить запись и вставить новую. 3. Записать пакет в таблицу №1. Возможно ли объединить в одном запросе к БД действия пунктов 1 и 2? И как, если возможно? |
| Автор: FINANSIST 2.6.2008, 08:11 | ||
| 1)Блин, ну ты даёшь - на фига такой геморой с таблицами. Такое решение задачи неприемлемо с точки зрения проектирования БД. Храни всё в одном пакете , ты вложенными запросами можешь сформировать любой селект с любыми критериями отбора, и не париться делая из 1 таблицы 2 . 2) Можешь за раз делать хоть сто запросов нажатием 1 кнопки на форме, только делай это програмно, через VBA
|
| Автор: Coder 2.6.2008, 08:24 |
| А если в основной таблице уже более 2000000 записей и это число быстро растет? И программу пишу я на Си с использованием MySQL API. Мне приходится 4 раза обращаться к БД, а хотелось бы 2. |
| Автор: Coder 2.6.2008, 08:43 |
| Приложение серверное, работать должно быстро. |
| Автор: FINANSIST 2.6.2008, 08:46 |
| SORRY! Не посмотрел что тема - MYSQL , все равно (ИМХО) решение деления одной таблицы на две ( с одинаковой структурой) только для ускорения выборки довольно странно. Вопрос изначально стоит именно в этом, а не в выполнении цепочки последовательных запросов. Я иногда дублирую таблицы - но это операция необходима для формировния временных срезов с дополнительной вставкой туда вычислений начальных, конечных сальдо, маржинальных доходов и прочих прелестей, (с последующим формированием из этого массива куба и очищением этой второй таблицы )но это вызванная необходимость. А зачем применять это в данном случае, не особо понятно. |
| Автор: Coder 2.6.2008, 08:54 |
| FINANSIST, смотри: Пользователь запрашивает - "дай мне последнюю информацию от ТОГО пользователя". Я, по коду пользователя, сообщение которого ищут, выдергиваю из таблицы №2 данные. Притом простейшим запросом - select * from table1 where (user_ud=3). Все! А табличка в которой миллионы записей лишний раз не перебирается, тем более что искать в ней самое свежее сообщение прийдется по полю ДатаВремя. |
| Автор: Feldmarschall 2.6.2008, 09:03 |
Для этого в БД придуманы индексы. или постой. ты правда выбираешь все записи пользователя, чтобы потом самостоятельно найти среди них одну нужную? А зачем? |
| Автор: FINANSIST 2.6.2008, 09:14 | ||
Если действительно в основной таблице "миллионы" записей и запрос последних , самых актуальных пакетов приходится делать очень часто, то реализованный подход кажется эффективным, однако если придется сделать иную выборку, то от сложных вложенных запросов тебе всё равно не уйти .
Принципиально не говорю о том, чего не знаю или в чём не уверен ( очень полезная в жизни превычка). Придётся соблюсти её и в даннос случае. Будут вопросы по ACCESS,EXCEL, VBA - обращайся! |
| Автор: Coder 2.6.2008, 09:53 | ||
| Feldmarschall, если поиск последних данных делать по сразу по таблице №1, то сначала выбираю все сообщения от нужного пользователя, а потом среди них ищу максимальную дату - так сейчас работает. Индексы есть, но нужно еще быстрее. Затем чтобы при написании кода в Си 1 раз сформировать буфер с текстом запроса к БД и передать его функции mysql_query() на выполнение. Ок. Спасибо! Добавлено @ 10:03 Вот Запросы и условия их выполнения, которые мне нужно запихнуть в 1 запрос к БД:
Можно ли реализовать такую условную ветку на MySQL? |
| Автор: Coder 2.6.2008, 12:48 | ||
Feldmarschall, МНЕ ТАК НУЖНО. Что зачем, что не пробывал? Много, что пробывал, для своей задачи я выбрал такой путь решения. Я не понял зачем эта вся писанина? Грубо говоря, я спрашиваю, можно ли вот это:
"запихать" в один запрос на языке SQL для СУБД mysql. |
| Автор: Feldmarschall 2.6.2008, 12:53 |
| Затем, что если ты сам не озаботился найти смысл в своих действиях, то подсказать тебе это. Я задал тебе просте вопросы, на которые несложно ответить. И отделить осмысленные действия от бессмысленных. Грубо говоря, так никто не делает. А если ты такой оригинальный, то не надо у других спрашивать, как сделать через нетрадиционное место. Молодец. Однако пробы должны подкрепляться минимальными теоретическими познаниями. В частности - умением работать с бд. Отсутствие которого ты наглядно демонстрируешь. В результате твой вопрос превращается в детский каприз. |
| Автор: skyboy 2.6.2008, 12:54 | ||
нет. в один нельзя. а теперь, может, давай поищем другие пути? |
| Автор: Coder 2.6.2008, 13:51 | ||
Я не против подсказки и хорошего совета, но все же хотелось услышать ответ на вопрос. skyboy, спасибо, теперь я знаю что так сделать нельзя. И можно поискать другие пути решения. В таблице следующие поля: id, user_id, date_time, message, param1, param2, ..., paramN Как вытащить последние данные для конкретного пользователя? Feldmarschall, таблица проиндексирована по полям id, user_id, date_time. |
| Автор: Feldmarschall 2.6.2008, 13:54 |
| другие искать надо не потому, что кривым нельзя, а потому что он - кривой. чем не устраивает запрос order by date_time desc limit 1? |
| Автор: Coder 2.6.2008, 14:03 | ||
У меня в локальной копии БД 1`965`603 записей, такой запрос в среднем выполняется за 1 секунду. Рабочий комп - Pentium M 1.6, 1Gb. Сервер конечно мощнее, но и данных там больше. |
| Автор: Akina 2.6.2008, 14:08 | ||
Это говорит об отсутствии индекса. Или об использовании неправильного индекса. давай начнем с цитирования структуры таблицы, включая индексы, и explain-а вот этого распоследнего запроса. |
| Автор: Feldmarschall 2.6.2008, 14:12 |
| возможно, может понадобиться составной индекс user_id, date_time Если в консоли выполнить запрос EXPLAIN select * from _info where (user_id=2) order by date_time desc limit 1; - что выведет? |
| Автор: Coder 2.6.2008, 14:16 | ||||||
Akina,
выдает:
|
| Автор: Feldmarschall 2.6.2008, 22:36 | ||
попробуй сделать
оно уберет filesort и должно стать быстрее. |
| Автор: Coder 3.6.2008, 02:35 |
| Feldmarschall, и правда! Теперь время выполнения такой выборки = 0.00. И колонка Extra показывает, что используется только where. Мне только не понятно, почему не был создан индекс при создании базы данных? Я же явно указал - KEY (date_time). Или тут дело именно в составном индексе? Feldmarschall, +1 |
| Автор: skyboy 3.6.2008, 03:20 |
два индекса использоваться не могут, а у тебя ведь условие по одному и сортировка по другому. потому составной ключ решил проблему. а ещё, так как where выполняется до сортировки, то порядок следования полей в объявлении индекса должен быть именно таким. |
| Автор: Feldmarschall 3.6.2008, 10:10 |
| Coder, насколько я себе это представляю. индекс - это файл, который, грубо говоря, состоит из пар "значение поля - позиция в файле", отсортированный по значению поля. Поиск по отсортированному списку происходит на порядки быстрее. В случае с одиночным индексом он используется, но помогает выбрать только строки одного юзера - а их 17 тысяч. А их уже приходится сортировать заново - ведь индекс по дате здесь не получится использовать - он тоже по всему файлу строится, и без информации о юзере. А составной индекс отсортирован по двум полям, то есть, имеет вид 1, 2001 1, 2002 1, 2003 2, 2001 2, 2005 5, 2008 соответственно, поиск сводится нахождению сначала юзера, а потом - максимальной даты для него. |
| Автор: Coder 4.6.2008, 04:09 |
| Feldmarschall, доходчиво. Помечаю вопрос ка решенный. |