PHP, MySQL, огромное соединение, скорость обработки

0

Это скорее теоретический запрос, чем что-либо другое, но у меня сложное объединение (в результате выше 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

Кажется, что это просто список индексов, поэтому мне это не помогает.

  • 1
    Вопросы о производительности не являются теоретическими и - даже больше, чем другие вопросы - нуждаются в теге для конкретной базы данных.
  • 0
    Если соединение выполняется слишком медленно, вам следует проверить, имеет ли каждое поле условия соединения индекс для этого поля.
Показать ещё 3 комментария
Теги:
performance
join

3 ответа

1

Поскольку вы используете основную таблицу 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 ...
  • 0
    Я не уверен, почему последовательность в первом указанном списке ...? Я бы подумал, что «Имя» должно быть первым полем? Конечно, я могу ошибаться, просто не понимаю.
  • 1
    С точки зрения оптимизации запросов нам необходимо различать два аспекта: «доступ» и «фильтрация». Доступ соответствует проверяемым строкам, и для оптимизации запроса мы хотим получить как можно меньшее количество строк. Во-вторых, нам нужно применить фильтры, которые будут отбрасывать строки, которые не соответствуют критериям. В вашем случае доступ должен быть по «NameCode». Во-вторых, ваш запрос не имеет фильтрации. Наконец, сортировка осуществляется по «Имени», и это только третье место.
Показать ещё 12 комментариев
0

После большой работы я обнаружил несколько проблем, которые мне удалось решить: я (считая, что это имеет смысл в то время), открывая некоторые таблицы, когда они не были нужны для подсчета строк; Я отказался от большого объединения и просто открыл подтаблицы по мере необходимости; очистил несколько других мест в коде; добавил еще несколько указателей на другой набор таблиц, которые не были в исходном соединении. Я смог уменьшить скорость от 4 минут до 45 секунд. В то время как 45 секунд занимает много времени, чтобы загрузить страницу, я считаю, что эта страница обрабатывала до 1500 (иногда больше) первичных записей и вытягивала данные из десяти разных таблиц, форматирования (таблицы внутри таблиц и т.д.), Что 45 секунд, вероятно, возможно, с запиской вверху страницы и индикатором выполнения, отображаемым при загрузке страницы. Спасибо всем. Индексы действительно помогли, и другие объяснения также помогли.

0

Во-первых, попробуйте удалить предложение "упорядочить по" и посмотреть, улучшает ли это что-либо. Иногда бывает так, что сам запрос выполняется быстро, но переупорядочение происходит медленно, требуя временных файлов.

Во-вторых, подайте запрос в оператор EXPLAIN (например, EXPLAIN SELECT whathaveyou FROM table...). Проверьте выходные данные для узких мест, отсутствующих индексов и т.д. (Https://dev.mysql.com/doc/refman/8.0/en/using-explain.html)

  • 0
    Я снял заказ, и он, похоже, ничего не изменил, с индексами, добавленными из сообщения The Impaler, загрузка страницы все еще занимает около 4 минут. См. Оригинальный пост (отредактированный), я использовал «EXPLAIN» и опубликовал то, что я сделал, и результаты.
  • 0
    @KenMayer «Использование временного; использование файловой сортировки» - вот что убивает производительность, вы должны попытаться выяснить, почему.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню