Имеется такая таблица:
CREATE TABLE IF NOT EXISTS `PrivateMessages` (
`iID` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '№',
`sCreateDate` datetime NOT NULL COMMENT 'Дата и время отправки',
`iSenderID` int(10) unsigned NOT NULL COMMENT '№ отправителя',
`sMessage` text NOT NULL COMMENT 'Сообщение',
`iRecipientID` int(10) unsigned NOT NULL COMMENT '№ получателя'
PRIMARY KEY (`iID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Приватные сообщения' AUTO_INCREMENT=1 ;
И вот такой запрос для обращения к ней:
SELECT * , IF( `iSenderID` = <userid>, `iRecipientID` , `iSenderID` ) AS `iCorrespondentID`
FROM (
SELECT *
FROM `PrivateMessages`
WHERE `iSenderID` = <userid> OR `iRecipientID` = <userid>
ORDER BY `iID` DESC
) AS `t`
GROUP BY `iCorrespondentID`
Как мы видим этот запрос является вложенным, что не есть хорошо для скорости его работы при больших объемах данных.
Помогите с него сделать два отдельных запроса по ключу. Заранее спасибо.
Спустя 11 минут, 1 секунда (29.08.2012 - 16:46) T1grOK написал(а):
Думаешь что то выиграешь? Сомневаюсь. И запрос детский. У меня есть БД к таблицам которой производится запрос с трех таблиц. В некоторых из этих таблиц больше полумиллиона записей.
Ничего работает как часы и очень быстро. Естественно индексы используются.
Ничего работает как часы и очень быстро. Естественно индексы используются.
Спустя 6 часов, 51 минута, 56 секунд (29.08.2012 - 23:38) ИНСИ написал(а):
Для того, чтобы упростить запрос, необходимо использовать нормализованную и продуманную базу данных. Иначе приходиться городить такие вот запросы.
Спустя 40 минут, 48 секунд (30.08.2012 - 00:19) sergeiss написал(а):
Я тут подумал, даже написал запрос, который (вроде как) делает то же самое, что и твой запрос. И без вложенности.
Но потом попытался понять, что ты хочешь получить - и не понял!
Сначала ты выбрал записи из таблицы, у которых в одном или в другом поле содержится определенная величина. Тут понятно. Далее - ты создаешь новую колонку с величиной из одного из определенных полей. А затем - ГРУППИРУЕШЬ. И при этом теряешь все записи из группы, кроме одной. Логика не понятна....
А запрос, вроде как, вот такой получается:
Можно добавить еще и ORDER BY, только, как я уже сказал, я не понял суть запроса.
Но потом попытался понять, что ты хочешь получить - и не понял!
Сначала ты выбрал записи из таблицы, у которых в одном или в другом поле содержится определенная величина. Тут понятно. Далее - ты создаешь новую колонку с величиной из одного из определенных полей. А затем - ГРУППИРУЕШЬ. И при этом теряешь все записи из группы, кроме одной. Логика не понятна....
А запрос, вроде как, вот такой получается:
SELECT * , IF( `iSenderID` = <userid>, `iRecipientID` , `iSenderID` ) AS `iCorrespondentID`
FROM `PrivateMessages`
WHERE `iSenderID` = <userid> OR `iRecipientID` = <userid>
GROUP BY `iCorrespondentID`
Можно добавить еще и ORDER BY, только, как я уже сказал, я не понял суть запроса.
Спустя 8 часов, 52 минуты, 26 секунд (30.08.2012 - 09:11) p.pavluxa написал(а):
Давайте рассмотрим личные сообщения vkontakte.ru (диалоги). Когда ты заходишь на главную страницу диалогов ты видишь список из пользователей с которыми ты общался + дату последнего сообщения + сам текст последнего сообщения.
Вот именно я этого же и добиваюсь, что бы показать пользователю список из тех с кем он общался, и к каждому собеседнику вывести последнюю дату сообщения и текст.
Вот именно я этого же и добиваюсь, что бы показать пользователю список из тех с кем он общался, и к каждому собеседнику вывести последнюю дату сообщения и текст.
Спустя 4 минуты, 37 секунд (30.08.2012 - 09:16) killer8080 написал(а):
Цитата (p.pavluxa @ 29.08.2012 - 17:35) |
Помогите с него сделать два отдельных запроса по ключу. |
Зачем?
Спустя 8 минут, 6 секунд (30.08.2012 - 09:24) p.pavluxa написал(а):
Для увеличения скорости работы, ведь если база будет пару гигобайт, при этом одновременно запрос выполниться раз 10, выделенный сервер умрёт.
Спустя 5 минут, 2 секунды (30.08.2012 - 09:29) killer8080 написал(а):
Цитата (p.pavluxa @ 30.08.2012 - 10:24) |
при этом одновременно запрос выполниться раз 10, выделенный сервер умрёт. |
А от двойных запросов ему точно станет легче
Ну дык расставь индексы по полям SenderID, iRecipientID, поиск то у тебя всегда по ним идет, а не по первичному ключу.
Спустя 3 минуты, 34 секунды (30.08.2012 - 09:32) p.pavluxa написал(а):
Дык а может базу данных по другому спроэктировать? Но как?
Спустя 51 минута, 10 секунд (30.08.2012 - 10:24) sergeiss написал(а):
А "мой" запрос чем не понравился? Вроде как то же выбирает? Только добавь ORDER BY.
Спустя 2 минуты, 24 секунды (30.08.2012 - 10:26) p.pavluxa написал(а):
Он возвращает максимум 1 строку, а нужно максимум и минимум количество пользователей с которыми ты общался
Спустя 11 минут, 48 секунд (30.08.2012 - 10:38) ИНСИ написал(а):
Как вариант:
1. discusion : id, fuser, suser, dateUpdate
2. messages: id, text, discusionId
1. discusion : id, fuser, suser, dateUpdate
2. messages: id, text, discusionId
Спустя 5 минут, 17 секунд (30.08.2012 - 10:43) sergeiss написал(а):
Цитата (p.pavluxa @ 30.08.2012 - 12:26) |
Он возвращает максимум 1 строку, а нужно максимум и минимум количество пользователей с которыми ты общался |
Твой начальный вопрос именно это и делает... Про максимум и минимум пользователей ты не спрашивал
Спустя 3 минуты, 4 секунды (30.08.2012 - 10:46) ИНСИ написал(а):
Цитата |
А "мой" запрос чем не понравился? Вроде как то же выбирает? Только добавь ORDER BY. |
Если в запросе используется GROUP BY, то ORDER уже не поможет. Он вытащит Первое сообщение, а не последнее.
Спустя 21 минута, 3 секунды (30.08.2012 - 11:07) killer8080 написал(а):
Цитата (ИНСИ @ 30.08.2012 - 11:46) |
Цитата А "мой" запрос чем не понравился? Вроде как то же выбирает? Только добавь ORDER BY. Если в запросе используется GROUP BY, то ORDER уже не поможет. Он вытащит Первое сообщение, а не последнее. |
Так и есть
Спустя 1 час, 11 минут, 42 секунды (30.08.2012 - 12:19) p.pavluxa написал(а):
Ещё варианты?
Спустя 23 минуты, 34 секунды (30.08.2012 - 12:42) sergeiss написал(а):
Опять этот кривой Мускуль грабли ставит... В Пострге подобный запрос делается легко и просто, и ORDER BY очень даже хорошо работает. Причем, без GROUP BY - но это если говорим о начальном запросе, как он был показан в теме.
Цитата (p.pavluxa @ 30.08.2012 - 14:19) |
Ещё варианты? |
Так что в итоге надо получить? "Максимум и минимум пользователей с которыми общался"? Я вот эту фразу, например, вообще не понял.
Спустя 1 час, 56 минут, 56 секунд (30.08.2012 - 14:39) p.pavluxa написал(а):
У нас имеется таблица в которой храняться сообщения. Есть ID кто отправил и есть ID кому отправил.
Нужно по конкретному ID пользователя получить ВЕСЬ список тех с кем он общался, при чём в каждой записи дату и последнее сообщение.
В этоге массив массивов вида:
(отправитель | получатель / собеседник) | дата (последняя) | сообщение(последнее)
Нужно по конкретному ID пользователя получить ВЕСЬ список тех с кем он общался, при чём в каждой записи дату и последнее сообщение.
В этоге массив массивов вида:
(отправитель | получатель / собеседник) | дата (последняя) | сообщение(последнее)