[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Оптимизация MYSQL запроса
p.pavluxa
Здравствуйте, уважаемые пользователи форума.

Имеется такая таблица:

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 написал(а):
Я тут подумал, даже написал запрос, который (вроде как) делает то же самое, что и твой запрос. И без вложенности.

Но потом попытался понять, что ты хочешь получить - и не понял!
Сначала ты выбрал записи из таблицы, у которых в одном или в другом поле содержится определенная величина. Тут понятно. Далее - ты создаешь новую колонку с величиной из одного из определенных полей. А затем - ГРУППИРУЕШЬ. И при этом теряешь все записи из группы, кроме одной. Логика не понятна....

А запрос, вроде как, вот такой получается:
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, выделенный сервер умрёт.

А от двойных запросов ему точно станет легче biggrin.gif
Ну дык расставь индексы по полям 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

Спустя 5 минут, 17 секунд (30.08.2012 - 10:43) sergeiss написал(а):
Цитата (p.pavluxa @ 30.08.2012 - 12:26)
Он возвращает максимум 1 строку, а нужно максимум и минимум количество пользователей с которыми ты общался

Твой начальный вопрос именно это и делает... Про максимум и минимум пользователей ты не спрашивал smile.gif

Спустя 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 уже не поможет. Он вытащит Первое сообщение, а не последнее.

Так и есть smile.gif

Спустя 1 час, 11 минут, 42 секунды (30.08.2012 - 12:19) p.pavluxa написал(а):
Ещё варианты?

Спустя 23 минуты, 34 секунды (30.08.2012 - 12:42) sergeiss написал(а):
Опять этот кривой Мускуль грабли ставит... smile.gif В Пострге подобный запрос делается легко и просто, и ORDER BY очень даже хорошо работает. Причем, без GROUP BY - но это если говорим о начальном запросе, как он был показан в теме.

Цитата (p.pavluxa @ 30.08.2012 - 14:19)
Ещё варианты?

Так что в итоге надо получить? "Максимум и минимум пользователей с которыми общался"? Я вот эту фразу, например, вообще не понял.

Спустя 1 час, 56 минут, 56 секунд (30.08.2012 - 14:39) p.pavluxa написал(а):
У нас имеется таблица в которой храняться сообщения. Есть ID кто отправил и есть ID кому отправил.

Нужно по конкретному ID пользователя получить ВЕСЬ список тех с кем он общался, при чём в каждой записи дату и последнее сообщение.

В этоге массив массивов вида:

(отправитель | получатель / собеседник) | дата (последняя) | сообщение(последнее)
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.