![]() |
|
Модераторы: skyboy |
![]()
|
|
| Coder |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 733 Регистрация: 13.12.2004 Репутация: 1 Всего: 11 |
Есть 2 таблицы:
№1 - основная - содержит все пришедшие пакеты; №2 - вспомогательная - содержит только самый свежий пакет от каждого пользователя. Такое разделение сделано, чтобы при запросе последнего сообщения не лопатить основную таблицу, а сразу выдавать последние данные. Сейчас запись нового пакета в БД осуществляется через 4 запроса: 1. Проверить, чтобы пришедшее время в пакете было больше чем время в таблице №2 от этого пользователя. 2. Если пакет свежее, из таблицы №2 удалить запись и вставить новую. 3. Записать пакет в таблицу №1. Возможно ли объединить в одном запросе к БД действия пунктов 1 и 2? И как, если возможно? |
|||
|
||||
| FINANSIST |
|
|||
|
Статус: Жив ![]() ![]() Профиль Группа: Участник Сообщений: 526 Регистрация: 11.4.2008 Где: Москва Репутация: нет Всего: 23 |
1)Блин, ну ты даёшь - на фига такой геморой с таблицами. Такое решение задачи неприемлемо с точки зрения проектирования БД. Храни всё в одном пакете , ты вложенными запросами можешь сформировать любой селект с любыми критериями отбора, и не париться делая из 1 таблицы 2 . 2) Можешь за раз делать хоть сто запросов нажатием 1 кнопки на форме, только делай это програмно, через VBA
Это сообщение отредактировал(а) FINANSIST - 2.6.2008, 08:11 -------------------- “...Брали корову рыжую одну, отдавать будем корову рыжую одну, чтобы не нарушать отчетности” Эдуард Успенский, “Каникулы в Простоквашино” |
|||
|
||||
| Coder |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 733 Регистрация: 13.12.2004 Репутация: 1 Всего: 11 |
А если в основной таблице уже более 2000000 записей и это число быстро растет? И программу пишу я на Си с использованием MySQL API. Мне приходится 4 раза обращаться к БД, а хотелось бы 2.
|
|||
|
||||
| Coder |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 733 Регистрация: 13.12.2004 Репутация: 1 Всего: 11 |
Приложение серверное, работать должно быстро.
|
|||
|
||||
| FINANSIST |
|
|||
|
Статус: Жив ![]() ![]() Профиль Группа: Участник Сообщений: 526 Регистрация: 11.4.2008 Где: Москва Репутация: нет Всего: 23 |
SORRY! Не посмотрел что тема - MYSQL , все равно (ИМХО) решение деления одной таблицы на две ( с одинаковой структурой) только для ускорения выборки довольно странно.
Вопрос изначально стоит именно в этом, а не в выполнении цепочки последовательных запросов. Я иногда дублирую таблицы - но это операция необходима для формировния временных срезов с дополнительной вставкой туда вычислений начальных, конечных сальдо, маржинальных доходов и прочих прелестей, (с последующим формированием из этого массива куба и очищением этой второй таблицы )но это вызванная необходимость. А зачем применять это в данном случае, не особо понятно. -------------------- “...Брали корову рыжую одну, отдавать будем корову рыжую одну, чтобы не нарушать отчетности” Эдуард Успенский, “Каникулы в Простоквашино” |
|||
|
||||
| Coder |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 733 Регистрация: 13.12.2004 Репутация: 1 Всего: 11 |
FINANSIST, смотри:
Пользователь запрашивает - "дай мне последнюю информацию от ТОГО пользователя". Я, по коду пользователя, сообщение которого ищут, выдергиваю из таблицы №2 данные. Притом простейшим запросом - select * from table1 where (user_ud=3). Все! А табличка в которой миллионы записей лишний раз не перебирается, тем более что искать в ней самое свежее сообщение прийдется по полю ДатаВремя. |
|||
|
||||
| Feldmarschall |
|
|||
|
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 3 Всего: 32 |
Для этого в БД придуманы индексы. или постой. ты правда выбираешь все записи пользователя, чтобы потом самостоятельно найти среди них одну нужную? А зачем? |
|||
|
||||
| FINANSIST |
|
|||
|
Статус: Жив ![]() ![]() Профиль Группа: Участник Сообщений: 526 Регистрация: 11.4.2008 Где: Москва Репутация: нет Всего: 23 |
Если действительно в основной таблице "миллионы" записей и запрос последних , самых актуальных пакетов приходится делать очень часто, то реализованный подход кажется эффективным, однако если придется сделать иную выборку, то от сложных вложенных запросов тебе всё равно не уйти .
Принципиально не говорю о том, чего не знаю или в чём не уверен ( очень полезная в жизни превычка). Придётся соблюсти её и в даннос случае. Будут вопросы по ACCESS,EXCEL, VBA - обращайся! -------------------- “...Брали корову рыжую одну, отдавать будем корову рыжую одну, чтобы не нарушать отчетности” Эдуард Успенский, “Каникулы в Простоквашино” |
|||
|
||||
| Coder |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 733 Регистрация: 13.12.2004 Репутация: 1 Всего: 11 |
Feldmarschall, если поиск последних данных делать по сразу по таблице №1, то сначала выбираю все сообщения от нужного пользователя, а потом среди них ищу максимальную дату - так сейчас работает.
Индексы есть, но нужно еще быстрее. Затем чтобы при написании кода в Си 1 раз сформировать буфер с текстом запроса к БД и передать его функции mysql_query() на выполнение. Ок. Спасибо! Добавлено @ 10:03 Вот Запросы и условия их выполнения, которые мне нужно запихнуть в 1 запрос к БД:
Можно ли реализовать такую условную ветку на MySQL? Это сообщение отредактировал(а) Coder - 2.6.2008, 10:04 |
|||
|
||||
| Feldmarschall |
|
|||
|
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 3 Всего: 32 |
||||
|
||||
| Coder |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 733 Регистрация: 13.12.2004 Репутация: 1 Всего: 11 |
Feldmarschall, МНЕ ТАК НУЖНО. Что зачем, что не пробывал? Много, что пробывал, для своей задачи я выбрал такой путь решения. Я не понял зачем эта вся писанина? Грубо говоря, я спрашиваю, можно ли вот это:
"запихать" в один запрос на языке SQL для СУБД mysql. Это сообщение отредактировал(а) Coder - 2.6.2008, 12:54 |
|||
|
||||
| Feldmarschall |
|
|||
|
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 3 Всего: 32 |
Затем, что если ты сам не озаботился найти смысл в своих действиях, то подсказать тебе это. Я задал тебе просте вопросы, на которые несложно ответить. И отделить осмысленные действия от бессмысленных.
Грубо говоря, так никто не делает. А если ты такой оригинальный, то не надо у других спрашивать, как сделать через нетрадиционное место. Молодец. Однако пробы должны подкрепляться минимальными теоретическими познаниями. В частности - умением работать с бд. Отсутствие которого ты наглядно демонстрируешь. В результате твой вопрос превращается в детский каприз. |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
нет. в один нельзя. а теперь, может, давай поищем другие пути? |
|||
|
||||
| Coder |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 733 Регистрация: 13.12.2004 Репутация: 1 Всего: 11 |
Я не против подсказки и хорошего совета, но все же хотелось услышать ответ на вопрос. skyboy, спасибо, теперь я знаю что так сделать нельзя. И можно поискать другие пути решения. В таблице следующие поля: id, user_id, date_time, message, param1, param2, ..., paramN Как вытащить последние данные для конкретного пользователя? Feldmarschall, таблица проиндексирована по полям id, user_id, date_time. |
|||
|
||||
| Feldmarschall |
|
|||
|
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 3 Всего: 32 |
другие искать надо не потому, что кривым нельзя, а потому что он - кривой.
чем не устраивает запрос order by date_time desc limit 1? Это сообщение отредактировал(а) Feldmarschall - 2.6.2008, 13:55 |
|||
|
||||
| Coder |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 733 Регистрация: 13.12.2004 Репутация: 1 Всего: 11 |
У меня в локальной копии БД 1`965`603 записей, такой запрос в среднем выполняется за 1 секунду. Рабочий комп - Pentium M 1.6, 1Gb. Сервер конечно мощнее, но и данных там больше. |
|||
|
||||
| Akina |
|
|||
|
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 106 Всего: 454 |
Это говорит об отсутствии индекса. Или об использовании неправильного индекса. давай начнем с цитирования структуры таблицы, включая индексы, и explain-а вот этого распоследнего запроса. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
| Feldmarschall |
|
|||
|
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 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; - что выведет? |
|||
|
||||
| Coder |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 733 Регистрация: 13.12.2004 Репутация: 1 Всего: 11 |
Akina,
выдает:
|
||||||
|
|||||||
| Feldmarschall |
|
|||
|
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 3 Всего: 32 |
попробуй сделать
оно уберет filesort и должно стать быстрее. |
|||
|
||||
| Coder |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 733 Регистрация: 13.12.2004 Репутация: 1 Всего: 11 |
Feldmarschall, и правда! Теперь время выполнения такой выборки = 0.00. И колонка Extra показывает, что используется только where.
Мне только не понятно, почему не был создан индекс при создании базы данных? Я же явно указал - KEY (date_time). Или тут дело именно в составном индексе? Feldmarschall, +1 Это сообщение отредактировал(а) Coder - 3.6.2008, 02:37 |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
два индекса использоваться не могут, а у тебя ведь условие по одному и сортировка по другому. потому составной ключ решил проблему. а ещё, так как where выполняется до сортировки, то порядок следования полей в объявлении индекса должен быть именно таким. |
|||
|
||||
| Feldmarschall |
|
|||
|
Новичок ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2641 Регистрация: 11.12.2007 Репутация: 3 Всего: 32 |
Coder, насколько я себе это представляю.
индекс - это файл, который, грубо говоря, состоит из пар "значение поля - позиция в файле", отсортированный по значению поля. Поиск по отсортированному списку происходит на порядки быстрее. В случае с одиночным индексом он используется, но помогает выбрать только строки одного юзера - а их 17 тысяч. А их уже приходится сортировать заново - ведь индекс по дате здесь не получится использовать - он тоже по всему файлу строится, и без информации о юзере. А составной индекс отсортирован по двум полям, то есть, имеет вид 1, 2001 1, 2002 1, 2003 2, 2001 2, 2005 5, 2008 соответственно, поиск сводится нахождению сначала юзера, а потом - максимальной даты для него. |
|||
|
||||
| Coder |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 733 Регистрация: 13.12.2004 Репутация: 1 Всего: 11 |
Feldmarschall, доходчиво.
Помечаю вопрос ка решенный. |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | MySQL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |