Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Оптимизировать запрос / 12 сообщений из 12, страница 1 из 1
24.01.2014, 11:29:24
    #38536503
webzilla
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
Данные:
В базе данных есть несколько таблиц материалов с одинаковыми полями. Пример: новости(news), статьи(articles), достопримечательности(attractions) и т. д. У всех них есть id, title, text
Некоторые типы материалов имеют точку на карте. Для хранения координат используется другая таблица, где кроме данных карты указаны mat_id и mat_type, где mat_type - тип материала, который совпадает с именем таблицы. Сейчас для получения всех точек на карте используется основной запрос, который выбирает все данные из таблицы карты. Потом куча запросов - по каждой строке выбираются данные материала из соответствующей таблицы материала.
Вопрос:
Можно ли оптимизировать выборку одним запросом? Вариант с изменением структуры БД не подходит
...
Рейтинг: 0 / 0
24.01.2014, 12:20:38
    #38536643
ScareCrow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
можно
...
Рейтинг: 0 / 0
24.01.2014, 12:28:34
    #38536668
webzilla
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
ScareCrow, Спасибо ))) Подтолкните пожалуйста в каком направлении двигаться
...
Рейтинг: 0 / 0
24.01.2014, 13:29:25
    #38536793
OlegROA
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
Можно в один запрос включить джойны на все таблицы материалов типа:
Код: sql
1.
2.
3.
4.
select coalesce(t1.title,t2.title,t3.title) as title, coalesce(t1.text,t2.text,t3.text) as text from map as m
left join table1 as t1 on (m.type=1 and m.id=t1.id)
left join table2 as t2 on (m.type=2 and m.id=t2.id)
left join table3 as t3 on (m.type=3 and m.id=t3.id)

Этот запрос для каждой строки из карты будет искать соответствие в связанных таблицах. Если в какой-либо таблице соответствие не будет найдено, то нужное поле этой таблицы будет иметь значение NULL. Функция coalesce выдаст значение поля только из той таблицы, где было найдено соответствие типа и ид.
Ну, или NULL, если такого соответствия не было найдено ни в одной таблице.
...
Рейтинг: 0 / 0
24.01.2014, 13:31:18
    #38536803
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
webzilla Вариант с изменением структуры БД не подходитОдин из стандартных подходов - использование [UNION-]вьюва в качестве объединяющей/унифицирующей прокладки.
...
Рейтинг: 0 / 0
24.01.2014, 13:55:38
    #38536862
webzilla
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
OlegROA, Спасибо. Думал в этом направлении, но при необходимости последующих доработок внесение дополнительной таблицы повлечет изменение кода, что нарушит гибкость. Вот если бы можно было сделать что-то наподобие
select mat_id, mat_type as tablename from map а дальше в запросе использовать tablename как переменную для обращения к соответствующей таблице и выбирать id, title
напишу ерунду, но может это объяснит в каком направлении я думаю
select id, title, map.mat_type as tablename from map
left join tablename on mat_id = id
...
Рейтинг: 0 / 0
24.01.2014, 15:01:20
    #38536977
OlegROA
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
Akina подсказал уже, как сделать гибкое решение - делаете VIEW-представление, в которое из всех нужных таблиц будут собираться записи. И в основном запросе будете использовать выборку только из этого VIEW-представления по уникальному коду материала.
При изменении/добавлении/удалении таблиц материалов прийдется редактировать только это VIEW-представление.

Основная здесь проблема - как сделать все идентификаторы из всех таблиц материалов уникальными.
Исходя из задачи выход только один - конструировать уникальный идентификатор из типа материала и внутреннего идентификатора материала в своей таблице.
Есть два варианта - каждой таблице назначить свой диапазон значений идентификаторов.
К примеру, дать на каждую таблицу по 100млн. записей. В этом случае уникальный идентификатор формируется как:
Код: sql
1.
mat.type*100000000 + mat.id


Второй вариант - использовать символьный идентификатор, который формируется из префикса - название типа материала и ид этого материала:
Код: sql
1.
concat(elt(mat.type,'news','art','attr'),'-',mat.id)



Т.е., сами таблицы материалов мы не трогаем, но во VIEW-представление "собираем" новую таблицу из нужных колонок и формируем уникальный идентифкатор материала по одному из вышеприведенному варианту.
Соответственно, выборку из карты делаем только с джойном по VIEW-представлению, подставляя в условие выборки ON поиск по сформированному идентификатору:
Код: sql
1.
2.
select mat.id,mat.title,mat.text from map as m
left join view_mat as mat on mat.id = (m.type*100000000 + m.id)

или
Код: sql
1.
2.
select mat.id,mat.title,mat.text from map as m
left join view_mat as mat on mat.id = concat(elt(m.type,'news','art','attr'),'-',m.id)



Выборка для формирования самого VIEW-представления будет примерно такой:
Код: sql
1.
2.
3.
4.
5.
6.
(select (1*100000000 + t1.id) as id,t1.title as title,t1.text as text from news as t1)
UNION
(select (2*100000000 + t2.id),t2.title,t2.text from articles as t2)
UNION
(select (3*100000000 + t3.id),t3.title,t3.text from attractions as t3)
ORDER BY id

или
Код: sql
1.
2.
3.
4.
5.
6.
(select concat('news-',t1.id) as id,t1.title as title,t1.text as text from news as t1)
UNION
(select concat('art-',t2.id),t2.title,t2.text from articles as t2)
UNION
(select concat('attr-',t3.id),t3.title,t3.text from attractions as t3)
ORDER BY id
...
Рейтинг: 0 / 0
24.01.2014, 15:46:10
    #38537046
webzilla
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
OlegROA, Большое спасибо. Извините за некомпетентность в моем следующем вопросе, но просветите пожалуйста. Каким образом формируется VIEW.
Чтобы выдать результат при запросе ко VIEW сначала запускается запрос, который формирует этот VIEW а затем выбирает данные из VIEW соответственно запросу или формируется VIEW а затем отлеживается изменение таблиц "входящих" в запрос формирования VIEW и обновляется? Или другое?
...
Рейтинг: 0 / 0
24.01.2014, 16:05:26
    #38537091
retvizan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
webzilla,

http://sqlinfo.ru/articles/info/9.html
Существует два алгоритма, используемых MySQL при обращении к представлению: MERGE и TEMPTABLE.

В случае алгоритма MERGE, MySQL при обращении к представлению добавляет в использующийся оператор соответствующие части из определения представления и выполняет получившийся оператор.

В случае алгоритма TEMPTABLE, MySQL заносит содержимое представления во временную таблицу, над которой затем выполняется оператор обращенный к представлению.
...
Рейтинг: 0 / 0
25.01.2014, 01:12:28
    #38537518
OlegROA
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
webzillaКаким образом формируется VIEW.Ответ в виде ссылки на статью уже дали. Я лишь добавлю, что можно воспринимать VIEW как некую таблицу, в которой реально нет данных. Т.е., создаем в базе VIEW и пишем в ней запрос на выборку данных из других таблиц. После сохранения эта VIEW будет храниться в базе как и прочие таблицы. При обращении к этой VIEW
Код: sql
1.
select * from my_view

автоматически запускается тот запрос, который прописан в свойствах этой VIEW и мы получаем результат такой двойной выборки.
Удобно в случаях типа Вашего - когда структуру базы менять нельзя или нужен достаточно сложный запрос, который будет использоваться часто в разных местах пользовательского приложения - вместо дублирования этого запроса просто ставим вызов нужной VIEW.
В последнем случае выигрышь еще и в том, что если нужно будет изменить запрос (изменились таблицы или изменилось условие), то не прийдется его менять в самой клиентской программе - просто изменим его в свойствах VIEW в базе!
...
Рейтинг: 0 / 0
25.01.2014, 07:10:07
    #38537554
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
webzillaOlegROA, Спасибо. Думал в этом направлении, ...

ты бы лучше подумал в направлении "а не прислать бы мне код запроса в этот замечательный форум на sql. ru".
...
Рейтинг: 0 / 0
25.01.2014, 11:27:07
    #38537597
Zukora
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизировать запрос
View оно симпатично. конечно, но не будет ли тут всегда full scan?
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Оптимизировать запрос / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]