Это скорее теоретический запрос, чем что-либо другое, но у меня сложное объединение (в результате выше 1900 записей в основной таблице, в сочетании со всеми таблицами результатов в соединении, показанном ниже), результирующая сеть страница занимает 5-10 минут на моей локальной машине для обработки и завершения строительства. Я понимаю, что это может быть много факторов, но я надеюсь получить некоторые подсказки. В основном я загружаю массив имен из двух таблиц (один из них является перекрестными ссылками, поэтому массив используется для сортировки данных по именам, со ссылками и полем, указывающим, является ли это перекрестной ссылкой), тогда, если имя не перекрестная ссылка, я выпускаю это соединение:
select
n.NameCode, n.AL_NameCode, n.Name, n.Name_HTML, n.Region, n.Local, n.Deceased,
n.ArmsLink, n.RollOfArms, n.Blazon, n.PreferredTitle, n.ShortBio,
n.HeadShotPhoto, n.HeadShotPhotographer, n.HeadShotContributor,
x.NameCode, x.NameAKA, x.AlternateName,
g.NameLink, g.'Group Name',
p.NameLink, p.'Relationship Type', p.'Related To Link',
p2.Position_ID, p2.NameLink, p2.'Position Held', p2.'Times Held',
p2.'Date Started', p2.'Date Ended', p2.Hyperlink as pos_Hyperlink,
p2.'Screentip Text',
a.'Name Link', a.Description, a.EventDate, a.Hyperlink, a.'Screentip Text',
a.ExternalLink
from who_names as n
left outer join who_crossref as x on n.NameCode=x.NameCode
left outer join who_groups as g on n.NameCode=g.NameLink
left outer join who_personal as p on n.NameCode=p.NameLink
left outer join who_positions as p2 on n.NameCode=p2.NameLink
left outer join who_arts as a on n.NameCode=a.'Name Link'
where n.NameCode = ?
order by n.Name desc, g.'Group Name', p2.'Date Started', a.EventDate;
Для вывода различных частей данных I:
1) Запустите таблицу, 2) Выведите имя и некоторую другую информацию в первой строке, 3) Затем, чтобы обрабатывать, скажем, группы (подгруппы, которые кто-то связывает себя внутри организации), я выпускаю:
mysqli_data_seek( $result, 0 ); // to rewind to top of data so we're at first row
и посмотреть, есть ли что-нибудь для обработки для подгрупп (не у всех есть что-то...), 4) Я повторяю для личных отношений и других разделов, возвращаясь к вершине данных и зацикливая назад, если есть что-то, что нужно обработать.
Когда закончите с этим человеком, я закрываю таблицу и возвращаюсь в массив к следующему имени и повторяю...
Хотя это работает, 5-10 минут - это способ долго загружать веб-страницу.
Я размышляю над идеями, чтобы решить эту проблему, но я не уверен, что это какой-то конкретный аспект моего кода. Вернулось ли это вернулось к началу набора строк? Это таблицы в браузере? Это комбинация обоих (очень возможно)? Программа слишком велика, чтобы публиковать ее здесь целиком. Я чувствую себя довольно неловко, как это разрешить, и надеюсь, что у кого-то есть несколько указателей, которые помогут мне ускорить обработку, и я надеюсь, что детали, которые я дал, достаточно, чтобы дать что-то для работы.
Основываясь на комментариях и отзывах ниже, в PHP Admin, я сделал следующее:
explain select n.NameCode, n.AL_NameCode, n.Name, n.Name_HTML, n.Region, n.Local, n.Deceased,
n.ArmsLink, n.RollOfArms, n.Blazon, n.PreferredTitle, n.ShortBio, n.HeadShotPhoto,
n.HeadShotPhotographer, n.HeadShotContributor,
x.NameCode, x.NameAKA, x.AlternateName,
g.NameLink, g.'Group Name',
p.NameLink, p.'Relationship Type', p.'Related To Link',
p2.Position_ID, p2.NameLink, p2.'Position Held', p2.'Times Held', p2.'Date Started',
p2.'Date Ended', p2.Hyperlink as pos_Hyperlink, p2.'Screentip Text',
a.'Name Link', a.Description, a.EventDate, a.Hyperlink, a.'Screentip Text',
a.ExternalLink
from who_names as n
left outer join who_crossref as x on n.NameCode=x.NameCode
left outer join who_groups as g on n.NameCode=g.NameLink
left outer join who_personal as p on n.NameCode=p.NameLink
left outer join who_positions as p2 on n.NameCode=p2.NameLink
left outer join who_arts as a on n.NameCode=a.'Name Link'
where n.NameCode=638
order by n.Name desc, g.'Group Name', p2.'Date Started', a.EventDate
Это вернулось:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE n const PRIMARY,ix1_names PRIMARY 4 const 1 Using temporary; Using filesort
1 SIMPLE x ref ix2_crossref ix2_crossref 4 const 1 NULL
1 SIMPLE g ref ix3_groups ix3_groups 4 const 3 NULL
1 SIMPLE p ref ix4_personal ix4_personal 4 const 1 NULL
1 SIMPLE p2 ref ix5_positions ix5_positions 4 const 13 NULL
1 SIMPLE a ref ix6_arts ix6_arts 4 const 28 NULL
Кажется, что это просто список индексов, поэтому мне это не помогает.
Поскольку вы используете основную таблицу SINGLE, а остальные члены - все OUTER JOIN
есть один самый важный индекс, который может сделать ваш запрос быстрее:
create index ix1_names on who_names (NameCode, Name);
Кроме того, вложенные петлевые соединения (NLJ) против связанных таблиц будут полезны для следующих индексов. Возможно, у вас уже есть несколько из них, поэтому проверьте, есть ли у вас их в первую очередь. Если вы этого не сделаете, создайте их:
create index ix2_crossref on who_crossref (NameCode);
create index ix3_groups on who_groups (NameLink);
create index ix4_personal on who_personal (NameLink);
create index ix5_positions on who_positions (NameLink);
create index ix6_arts on who_arts ('Name Link');
Но опять же, это первый, который я считаю самым важным.
Вам нужно будет проверить реальность, чтобы увидеть, улучшается ли производительность с ним/им.
Если запрос все еще медленный, пожалуйста, извлеките план выполнения, как предлагалось @memo, используя:
explain select ...
После большой работы я обнаружил несколько проблем, которые мне удалось решить: я (считая, что это имеет смысл в то время), открывая некоторые таблицы, когда они не были нужны для подсчета строк; Я отказался от большого объединения и просто открыл подтаблицы по мере необходимости; очистил несколько других мест в коде; добавил еще несколько указателей на другой набор таблиц, которые не были в исходном соединении. Я смог уменьшить скорость от 4 минут до 45 секунд. В то время как 45 секунд занимает много времени, чтобы загрузить страницу, я считаю, что эта страница обрабатывала до 1500 (иногда больше) первичных записей и вытягивала данные из десяти разных таблиц, форматирования (таблицы внутри таблиц и т.д.), Что 45 секунд, вероятно, возможно, с запиской вверху страницы и индикатором выполнения, отображаемым при загрузке страницы. Спасибо всем. Индексы действительно помогли, и другие объяснения также помогли.
Во-первых, попробуйте удалить предложение "упорядочить по" и посмотреть, улучшает ли это что-либо. Иногда бывает так, что сам запрос выполняется быстро, но переупорядочение происходит медленно, требуя временных файлов.
Во-вторых, подайте запрос в оператор EXPLAIN (например, EXPLAIN SELECT whathaveyou FROM table...). Проверьте выходные данные для узких мест, отсутствующих индексов и т.д. (Https://dev.mysql.com/doc/refman/8.0/en/using-explain.html)