SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 04.09.2008 11:37:23

am001
Участник
Зарегистрирован: 04.09.2008
Сообщений: 5

Вопрос: Динамические уникальные элементы

Добрый день.
Подскажите, пожалуйста, как сделать такую выборку:
В таблице есть поле с номерами устройств DeviceId.
Задача: получить поля с максимальными значениями Индексов для каждого из устройств. Но устройства могут добавляться!

Вот пример запроса для выдачи информации от 2 устройств.

SELECT * FROM `table` WHERE `Index` = (SELECT MAX(`Index`) FROM `table` WHERE `DeviceId` = 1) OR `Index` = (SELECT MAX(`Index`) FROM `table` WHERE `DeviceId` = 2)


Подскажите, как можно сначала узнать количество уникальных DeviceId и потом уже подставить каждое уникальное в вышенаписаный код?

Неактивен

 

#2 04.09.2008 12:18:50

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Вопрос: Динамические уникальные элементы

SELECT * FROM `table` WHERE `index` IN (SELECT MAX(`index`) FROM `table` GROUP BY 'DeviceId`);

Неактивен

 

#3 04.09.2008 13:51:29

am001
Участник
Зарегистрирован: 04.09.2008
Сообщений: 5

Re: Вопрос: Динамические уникальные элементы

Спасибо.
Не подскажете, можно как-нибудь оптимизировать эти действия? Может как-то проиндексировать специально?
Просто в базе более 200 000 записей и такой запрос выполняется очень долго...
Может как-то заранее сделать, допустим, отдельное поле какое-то?

Неактивен

 

#4 04.09.2008 13:59:54

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Вопрос: Динамические уникальные элементы

ALTER TABLE `table` ADD INDEX (`DeviceID`, `index`);
ALTER TABLE `table` ADD INDEX (`index`);

Это создаст индексы, по которым такой запрос должен выполняться очень быстро.

Неактивен

 

#5 04.09.2008 14:02:38

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Вопрос: Динамические уникальные элементы

Возможно, запрос стоит переписать в виде объединения двух таблиц - так он может работать
быстрее (опять же, на этих индексах):

SELECT t1.*
FROM `table` t1
JOIN (SELECT MAX(`index`) as `index` FROM `table` GROUP BY 'DeviceId`) t2 USING (`index`);

Неактивен

 

#6 04.09.2008 14:26:15

am001
Участник
Зарегистрирован: 04.09.2008
Сообщений: 5

Re: Вопрос: Динамические уникальные элементы

Спасибо, буду пробовать.

Неактивен

 

#7 08.09.2008 10:16:49

am001
Участник
Зарегистрирован: 04.09.2008
Сообщений: 5

Re: Вопрос: Динамические уникальные элементы

Подскажите, как сделать в таком случае немного по-другому, а именно:
- создать 2 таблицы:
1 - таблица со всеми данными, в т.ч. 'DeviceId'
2 - таблица с одним полем 'DeviceId'

Т.е. при добавлении данных в 1 таблицу, проверять, есть ли DeviceId во второй. Если нет - добавлять его туда.
А уже потом при запросе максимального значения каждого DeviceId просто выбирать из таблицы 2 список DeviceId (их там будет 5-10), и потом уже по этим 5-10 значениям производить поиск по 1 таблице!!

Это должно значительно ускорить работу БД!

Подскажите, пожалуйста, знающие люди, как можно реализовать такой подход?

Неактивен

 

#8 08.09.2008 13:45:32

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Вопрос: Динамические уникальные элементы

Честно говоря, не понял, зачем Вам нужна отдельная таблица с одним полем DeviceId.
Для того, чтобы вручную сформировать запрос по первой таблице? А чем Вам не нравится
группировка?

Неактивен

 

#9 08.09.2008 13:52:31

Sign
Гуру
Зарегистрирован: 26.06.2008
Сообщений: 43

Re: Вопрос: Динамические уникальные элементы

paulus написал:

... А чем Вам не нравится группировка?

В принципе нормальный подход денормализации - хранить в отдельной таблице результаты группировки, складывая их туда после апдейтов

Неактивен

 

#10 08.09.2008 13:56:29

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Вопрос: Динамические уникальные элементы

Если делать денормализацию - то лучше уж тогда сделать отдельную табличку с 2 полями
(DeviceID, Max_index) - по ней можно точечно выбрать данные по основному запросу.

Неактивен

 

#11 08.09.2008 14:57:50

am001
Участник
Зарегистрирован: 04.09.2008
Сообщений: 5

Re: Вопрос: Динамические уникальные элементы

paulus написал:

Если делать денормализацию - то лучше уж тогда сделать отдельную табличку с 2 полями
(DeviceID, Max_index) - по ней можно точечно выбрать данные по основному запросу.

Подскажите, пожалуйста, как это организовать?
Т.е. как сделать, чтобы при отсылке записи в БД шла проверка на DeviceID и Max_index?


Сейчас отсылка идёт просто 1 командой в одну таблицу:
INSERT INTO table1 (DeviceId, .......) VALUES ('$deviceid', ..........)";

Неактивен

 

#12 08.09.2008 16:34:44

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Вопрос: Динамические уникальные элементы

Ну и сделайте еще UPDATE table2 SET maxindex = IF(maxindex < $idx, $idx, maxindex) WHERE DeviceID=$deviceid;

Неактивен

 

#13 08.09.2008 17:55:33

Sign
Гуру
Зарегистрирован: 26.06.2008
Сообщений: 43

Re: Вопрос: Динамические уникальные элементы

Или вот-так

DELIMITER |
CREATE TRIGGER tr_mx AFTER INSERT ON `table`
  FOR EACH ROW BEGIN
        set @m = (select max(`index`) from table where device_id=NEW.device_id);
    INSERT INTO table2 SET maxindex = @m, device_id=NEW.device_id
            ON DUPLICATE KEY UPDATE maxindex = @m;
  END;
|

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson