|
|
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
Короче я понял одно. Надо углубляться в познании SQL. =) Задача не решена, пока. Но в любом случае спасибо за активную помощь всем. Такой отзывчивости я не ожидал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2016, 19:52 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
polgerКороче я понял одно. Надо углубляться в познании SQL. =) Задача не решена, пока. Но в любом случае спасибо за активную помощь всем. Такой отзывчивости я не ожидал. Вам нужно всего 2 вещи: - переделать структуру как уже выше говорили - понять что выводить сразу 20к записей еще тот бред. Вы можете экспортировать данные в эксель и там их просматривать. Мускул это БД а не клиент. Разбейте вывод по 10-20 записей на страницу и будет вам счастье в том же мускуле. P.S. Улыбнуло хранение возраста и т.п. в отдельных таблицах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2016, 20:32 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
Злой БобрУлыбнуло хранение возраста и т.п. в отдельных таблицах.А что в этом плохого? ну или хотя бы просто необычного? речь ведь не идёт об отдельной таблице для хранения только возраста... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2016, 20:37 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
Akina, Ну обычно в таблице ставят поле дата и указывают для каждой записи дату рождения. Возраст считается уже исходя из разницы текущей даты и даты рождения. У автора же извращенный EAV. В принципе ничего особенного - стандартная ошибка "студента". Поэтому и улыбнуло а не подорвало. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2016, 22:00 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
Akina... речь ведь не идёт об отдельной таблице для хранения только возраста... У автора как раз это и есть. ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2016, 22:01 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
Итак опыт "студента" показал. Дописал я запрос до 26 джоинов, 50 - это я утрировал, осталось дописать подключение шести таблиц многое к многому но я не об этом. Заменил я INNER на LEFT, как советовал DirksDR и всё отработало за пол секунды (запросы делаю в phpmyadmin со стандартным выводом в 25 записей на страницу). Ради чистоты эксперимента заменил на INNER, запрос обрабатываться будет до следующего пришествия. Процессор пашет на 100%. Вот объясните знатоки, почему такая разница во времени исполнения? Разницу между INNER и LEFT я понимаю, мне как раз и нужно, что бы в результате были все пользователи не зависимо от заполненности данными. И про структуру, пожалуйста, ничего не говорите, так надо =) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2016, 23:14 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
polgerКороче я понял одно. Надо углубляться в познании SQL. =) Задача не решена, пока. Но в любом случае спасибо за активную помощь всем. Такой отзывчивости я не ожидал. А не проще пока суть да дело, за раз выбирать не все 50 атрибутов, а какую-то их часть одним запросом, другую часть следующим, ну и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2016, 23:15 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
schi, Я первый =) Вопрос ко всем: Будет ли мной вышесказанное означать, что когда количество данных удвоится, то и удвоится время обработки этого запроса? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2016, 23:34 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
polger Вот объясните знатоки, почему такая разница во времени исполнения? Разницу между INNER и LEFT я понимаю, мне как раз и нужно, что бы в результате были все пользователи не зависимо от заполненности данными.В INNER оптимизатор волен выбирать любой порядок соединения таблиц. При 50 джойнах возникает 51! комбинаций последовательности таблиц. Это явно слишком много и оптимизатор скорее всего выбирает не тот вариант. А при LEFT порядок соединения таблиц всегда четко определен, ведущая слева. И оптимизатору просто не остается пространства для неверного выбора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 00:44 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
polgermiksoft, Если я не ошибаюсь в синтаксисе, пишу с телефона по памяти, то у меня примерно следующее: SELECT cit.value, cou.value FROM users u INNER JOIN table_city cit ON u.city = cit.id INNER JOIN table_country cou ON u.country = cou.id ... И так 50 раз Не правильно? Запросы выполняю в phpmyadmin В таблице users 20 000 тестовых записей.Еще должно быть условие на таблицу users в секции WHERE, иначе это будет выборка всех пользователей с огромными затратами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 00:46 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
polgerВопрос ко всем: Будет ли мной вышесказанное означать, что когда количество данных удвоится, то и удвоится время обработки этого запроса?Нет, при правильной индексации время выполнения такого рода запросов растет примерно логарифмически (пока хватает всяких кэшей и буферов.) относительно количества данных, что значительно медленнее, чем линейно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 00:48 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
miksoftВ INNER оптимизатор волен выбирать любой порядок соединения таблиц.Если не использовать STRAIGHT_JOIN - а в данном случае его лучше таки использовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 07:39 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
miksoftВ INNER оптимизатор волен выбирать любой порядок соединения таблиц. При 50 джойнах возникает 51! комбинаций последовательности таблиц. Это явно слишком много и оптимизатор скорее всего выбирает не тот вариант. Откуда взялось 51! ? Если существует ровно один вариант соединения двух таблиц, зачем перебирать другие ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 10:24 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
schiЕсли существует ровно один вариант соединения двух таблиц, зачем перебирать другие ?Даже для двух таблиц есть два варианта - сперва читать первую, потом вторую, или сделать наоборот. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 10:36 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
schiОткуда взялось 51! ?Количество перестановок . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 10:58 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
Akina, miksoft Коллеги, я наверное действительно чего-то не понимаю. Не будете ли так любезны ткнуть ссылкой в описание оптимизатора, который работает описываемым вами образом ? Если у ТС-а есть связи между таблицами, то зачем читать все таблицы целиком, достаточно прочитать связующие, не так ли ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 11:07 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
schiЕсли у ТС-а есть связи между таблицами, то зачем читать все таблицы целиком, достаточно прочитать связующие, не так ли ?Если под связями подразумеваются внешние ключи, то они помогают оптимизатору не более, чем обычный индекс. Но они не принуждают оптимизатор выполнять запрос именно в направлении этих связей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 11:12 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
schiНе будете ли так любезны ткнуть ссылкой в описание оптимизатора, который работает описываемым вами образом ?Не совсем то, но близко: http://dev.mysql.com/doc/refman/5.7/en/left-join-optimization.html The join optimizer calculates the order in which tables should be joined. The table read order forced by LEFT JOIN or STRAIGHT_JOIN helps the join optimizer do its work much more quickly, because there are fewer table permutations to check. Кстати, там же есть важный момент, про который часто забывают: http://dev.mysql.com/doc/refman/5.7/en/left-join-optimization.html For a LEFT JOIN, if the WHERE condition is always false for the generated NULL row, the LEFT JOIN is changed to a normal join. For example, the WHERE clause would be false in the following query if t2.column1 were NULL: Код: sql 1. Therefore, it is safe to convert the query to a normal join: Код: sql 1. This can be made faster because MySQL can use table t2 before table t1 if doing so would result in a better query plan. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 11:30 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
miksoftНе совсем то, но близко: ... Видимо я неудачно выразился. Я бы хотел увидеть подтверждение, что для соединения N таблиц оптимизатор MySQL всегда будет выполнять (N+1)! попыток соединить таблицы в разных сочетаниях. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 12:22 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
А вообще, прежде чем дальше давать советы, было бы интересно от ТС-а получить DDL хотя бы на главную таблицу и на пару подчиненных ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 12:24 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
schiЯ бы хотел увидеть подтверждение, что для соединения N таблиц оптимизатор MySQL всегда будет выполнять (N+1)! попыток соединить таблицы в разных сочетаниях.Нет, перебранных сочетаний будет гораздо меньше. Оптимизатор при выборе порядка соединения ориентируется на статистику таблиц, причём "плюс-минус лапоть", так что часть таблиц будет им заведомо задвинута. А вот все сочетания тех, что более-менее, он переберёт. Подтверждение или опровержение можешь поискать на MySQL Internals или в исходном коде. Буде не лень... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 12:26 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
Так что, берём на веру что ничего менять нельзя и мучаемся как быстро склеить 50 таблиц? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 12:41 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
schimiksoftНе совсем то, но близко: ... Видимо я неудачно выразился. Я бы хотел увидеть подтверждение, что для соединения N таблиц оптимизатор MySQL всегда будет выполнять (N+1)! попыток соединить таблицы в разных сочетаниях.Ну непосредственно (N+1)! он не будет пытаться перебрать, ибо на этого никакого времени не хватит, это лишь теоретический предел. Оптимизатор будет перебирать до некоторого своего предела. В Оракле он настраивается, насколько я помню, а в MySQL такой настройки я не нашел. Оптимизатор так же учитывает наличие индексов и старается строить план так, чтобы их использовать. См. также http://dev.mysql.com/doc/internals/en/optimizer-joins-access-methods.html Собственно, поэтому проблема ТС и возникла, что оптимизатор в своем переборе не доходит до оптимального плана и используется неподходящий порядок соединения таблиц, вероятно, в совокупности с отсутствием нужных индексов. P.S. Хотя, возможно, мы это все перемудрили, а в запросе просто какая-то банальная ошибка :) Мы же полного текста запроса и его плана не видели. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 12:44 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
alex564657498765453Так что, берём на веру что ничего менять нельзя и мучаемся как быстро склеить 50 таблиц?Зачем мучаться-то? Помогаем оптимизатору (указанием LEFT или STRAIGHT_JOIN) и едем дальше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 12:46 |
|
||
|
Сджойнить 50 таблиц
|
|||
|---|---|---|---|
|
#18+
miksoftОптимизатор будет перебирать до некоторого своего предела. В Оракле он настраивается, насколько я помню, а в MySQL такой настройки я не нашел. Что происходит в Oracle, довольно подробно у Льюиса описано. miksoftХотя, возможно, мы это все перемудрили, а в запросе просто какая-то банальная ошибка :) Мы же полного текста запроса и его плана не видели. И DDL мы тоже не видели, может там индексов/constraints нет совсем, тогда на 20 тысячах записей можно такой картезианский продукт получить, что недели не хватит его перебрать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2016, 12:54 |
|
||
|
|

start [/forum/topic.php?fid=47&msg=39345192&tid=1831215]: |
0ms |
get settings: |
7ms |
get forum list: |
18ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
184ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
| others: | 242ms |
| total: | 522ms |

| 0 / 0 |
