Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите оптимизировать, запрос "матрешка" 
V
    Опции темы
DonPager
Дата 29.6.2011, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Колдырь
**


Профиль
Группа: Участник
Сообщений: 327
Регистрация: 28.3.2003
Где: Воронеж

Репутация: нет
Всего: 2



Дрась,
есть запрос из 3х таблиц:
EventLog(id,map_id,...)
NodeTable(id,node_id, parent_id, label,...)
Subnets (id, subnet_id , label,...)

Код

select id, date_time, priority, trim(message) as Mes, map_id,
    (select label from NodeTable where node_id=map_id order by id desc limit 1) NodeName,
    (Select label from Subnets where subnet_id in(select parent_id from NodeTable where node_id=map_id)order by id desc limit 1) as SubNetName    
from EventLog
where priority<7
order by EventLog.id desc 
limit 50;


Запрос корректно отрабатывает, но долго :( хочется оптимизировать. Чувствую, что нужно как-то избавиться от подзапроса
Код

(select parent_id from NodeTable where node_id=map_id)order by id desc limit 1)

но не дам ума как. джоин тут не канает - т.к. в NodeTable и Subnets записи не уникальные и нужны последние из них

база mysql

Спасибо.


--------------------
кодер + лодырь = колдырь
PM MAIL ICQ Skype GTalk   Вверх
Zloxa
Дата 29.6.2011, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



индексы:  NodeTable (node_id,id), Subnets(subnet_id, id), EventLog(priority,id)



--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
DonPager
Дата 29.6.2011, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Колдырь
**


Профиль
Группа: Участник
Сообщений: 327
Регистрация: 28.3.2003
Где: Воронеж

Репутация: нет
Всего: 2



Текущую структуру БД менять нельзя :( есть доступ только на чтение
сейчас стоят одномерные индексы (id) для каждой из таблиц и менять их врятли кто-то будет

UPD: если бы можно было  переделали бы структуру с добавлением historySubnets, historyNodes -  но нельзя :(

Это сообщение отредактировал(а) DonPager - 29.6.2011, 11:03


--------------------
кодер + лодырь = колдырь
PM MAIL ICQ Skype GTalk   Вверх
Zloxa
Дата 29.6.2011, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(DonPager @  29.6.2011,  10:59 Найти цитируемый пост)
 одномерные индексы (id) 

они для этого запроса - бесполезны.
Цитата(DonPager @  29.6.2011,  10:59 Найти цитируемый пост)
Текущую структуру БД менять нельзя

тогда ничего больше не остается, поможет только хинт do_it_fast  smile /*сарказм*/


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
triclosan
Дата 29.6.2011, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006

Репутация: 3
Всего: 12



DonPager, Что-то запрос у вас мутный уж очень, может опишите структуру и что вы выбираете из них?
Цитата(DonPager @  29.6.2011,  10:28 Найти цитируемый пост)
select label from NodeTable where node_id=map_id order by id desc limit 1

вот этот подзапрос и подобные сильно отдают некорректностью.

PM MAIL   Вверх
DonPager
Дата 29.6.2011, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Колдырь
**


Профиль
Группа: Участник
Сообщений: 327
Регистрация: 28.3.2003
Где: Воронеж

Репутация: нет
Всего: 2



таблица EventLog
Код

select id, date_time, message, map_id from EventLog  where priority<3 limit 10;

user posted image

таблица NodeTable
Код

#Первая строчка из пред. запроса
select id,node_id,label, parent_id from NodeTable where node_id='8237551-48217'; 

user posted image

таблица Subnets
Код

#Первая строчка из пред. запроса
select id,subnet_id,label, parent_id from Subnets where subnet_id='8237551-652';  

user posted image


--------------------
кодер + лодырь = колдырь
PM MAIL ICQ Skype GTalk   Вверх
triclosan
Дата 29.6.2011, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006

Репутация: 3
Всего: 12



скиньте пожалуйста дамп таблиц (по десятку записей хотя бы)
PM MAIL   Вверх
Zloxa
Дата 29.6.2011, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(triclosan @ 29.6.2011,  11:43)
Цитата(DonPager @  29.6.2011,  10:28 Найти цитируемый пост)
select label from NodeTable where node_id=map_id order by id desc limit 1

вот этот подзапрос и подобные сильно отдают некорректностью.

Мне не понятно где ты видишь некорректность. Как еще "более корректно" выбрать лабел ноды со старшим номером версии? Я так понимаю версия определяется, судя по всему, автоинкрементом, потому по недоумию названа id, и, возможно даже определена как ПК, чтобы прочнее сбивать с толку ))

Если сделать alter  table NodeTable rename id to version#, отдача некорректностью не устранится ли?  smile 

Это сообщение отредактировал(а) Zloxa - 29.6.2011, 14:47


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
DonPager
Дата 29.6.2011, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Колдырь
**


Профиль
Группа: Участник
Сообщений: 327
Регистрация: 28.3.2003
Где: Воронеж

Репутация: нет
Всего: 2



Цитата

скиньте пожалуйста дамп таблиц (по десятку записей хотя бы) 

А чем не устраивает данная иллюстрация?

В абстрактном варианте вот вариант:
А(id,data,iKey)=
(1,'A','10'),
(2,'B','11')

B(id,key,data,sKey)=
(1,'10','AAA','20'),
(2,'10','BBB','20'),
(3,'11','CCC','20'),
(4,'12','DDD','21')

C(id,key,data)=
(1,'20','aaa'),
(2,'20','bbb'),
(3,'11','ccc'),
(4,'12','ddd')

Код

select id, data, iKey,
    (Select data from B where key=A.iKey order by id desc limit 1),
    (Select data from C where key in(select sKey from B where key=A.iKey)order by id desc limit 1) 
from A;

Выдаст (что и требуется):
1, 'A', '10', 'BBB','bbb'
2, 'B', '11', 'CCC', 'bbb'

Остаётся только оптимизировать запрос - в этом и вопрос КАК?





--------------------
кодер + лодырь = колдырь
PM MAIL ICQ Skype GTalk   Вверх
triclosan
Дата 29.6.2011, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006

Репутация: 3
Всего: 12



Цитата(Zloxa @  29.6.2011,  14:46 Найти цитируемый пост)
Мне не понятно где ты видишь некорректность. 

Виноват, мне там group by привиделся, ну а если придираться, то limit в подзапросах это не очень хорошо - во-первых это кажись не поддерживается в старых версиях сервера, во-вторых делает запрос mysql-зависимым


Код

select T.id, T.data, T.ikey, B.data, C.data
from B, C,
(select A.id, A.data, A.ikey, max(B.Id) as max_bid, max(C.id) as max_cid
from A, B, C
where 
A.ikey = B.key
and B.skey = C.key
group by A.id, A.data, A.ikey) T
where B.id = T.max_bid
and C.id = T.max_cid

не уверен, что стало лучше  smile 

Это сообщение отредактировал(а) triclosan - 29.6.2011, 15:59
PM MAIL   Вверх
DonPager
Дата 29.6.2011, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Колдырь
**


Профиль
Группа: Участник
Сообщений: 327
Регистрация: 28.3.2003
Где: Воронеж

Репутация: нет
Всего: 2



Цитата(triclosan @  29.6.2011,  07:33 Найти цитируемый пост)
не увере, что стало лучше    


не только НЕ лучше, но и хуже -  при лимите в 50 записей мой вариант - 5 сек, твой - 9

за сим думаю решено поставлю  - ибо чуда не произошло.



--------------------
кодер + лодырь = колдырь
PM MAIL ICQ Skype GTalk   Вверх
triclosan
Дата 29.6.2011, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006

Репутация: 3
Всего: 12



DonPager, лимит тут ни при чем, он отрезает все, после 50 строки после полной выборки по всей таблице, можно сделать ухищрение типа EventLog.id > HINT_VALUE, где хинт порог выборки "чуть больше, чем 50"

PM MAIL   Вверх
DonPager
Дата 29.6.2011, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Колдырь
**


Профиль
Группа: Участник
Сообщений: 327
Регистрация: 28.3.2003
Где: Воронеж

Репутация: нет
Всего: 2



Имелось в виду, что выборку в подзапросе отфильтровл до 50 записей с уникальным id ... -но  это не суть
чуда то всё равно не произошло =)... наверное забыл дунуть(с) Акопян


--------------------
кодер + лодырь = колдырь
PM MAIL ICQ Skype GTalk   Вверх
triclosan
Дата 29.6.2011, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 515
Регистрация: 18.8.2006

Репутация: 3
Всего: 12



Фильтрование лимитом не приведет к ускорению работы запроса, если вас это устроит можете выполнять предварительный запрос для анализа по какому значению id фильтровать как-то так:

Код

SET @rank:=0;
select max(AT.id) from (
select @rank:=@rank+1 as rank1, A.id 
from A
order by A.id desc
) AT
where AT.rank1 <= 50;


или у вас не каждому A.id отвечают записи в таблицах B, C?
PM MAIL   Вверх
Zloxa
Дата 29.6.2011, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



DonPager, 6 секунд это не то время, которое имеет смысл оптимизировать, если запрос одноразовый и к чужой базе. Если же база своя и запрос не одноразовый, а продуктивный, то Вы, как минимум - разраб. Скажите пожалуйста, какая именно религия вас побуждает ожидать чудес вместо построения необходимых индексов?


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Составление SQL-запросов | Следующая тема »


 




[ Время генерации скрипта: 0.1262 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.