Как написать/оптимизировать SQL-запрос, который должен выбирать данные из 6 связанных таблиц, пока он не получит то, что ему нужно

Я пишу PHP-приложение, построенное на базе данных MySQL, созданное для 5-6 приложений, разделяющих его. Из-за этого я не могу изменить структуру базы данных, и я знаю, что многие из вас скажут сначала сделать это, но, к сожалению, я не могу.

Вот моя скрипка SQL схемы базы данных, запрос, который я использую, и желаемый результат:

http://sqlfiddle.com/#!2/de7493/1

Мое решение работает с этой базой данных, но с реальной производственной базой, где некоторые из этих таблиц имеют более 1 млн строк, когда я пытаюсь запустить ее, происходит сбой БД. Даже если я урежу этот sql, чтобы выбрать только из 3-4 таблиц, он все равно будет крашиться. Может быть, это невозможно сделать, может быть, я делаю это неправильно. Вот что я должен сделать:

Я динамически получаю cpv_id из URL-адреса. В моем примере cpv_id равен 66113000. Основываясь на этом значении, я должен выяснить, какие клубные предложения связаны с этим cpv_id. Затем на основе этих предложений я должен выяснить, у каких членов клуба есть некоторые из этих предложений. (члены клуба - компании). Затем, основываясь на идентификаторе члена клуба, я должен найти некоторую информацию о компании, которая является членом клуба, среди этих данных я должен найти компанию special_id. И на основе этого special_id я должен читать отчеты компании.

Итак, в основном: на основе cpv_id я должен найти отчеты компании для компании, имеющей клубные предложения, связанные с этим идентификатором (просто, верно?). Как видно из того, как мои таблицы связаны в SQLFiddle, мне нужно пройти через 6 таблиц, чтобы получить то, что мне действительно нужно. Еще раз, я не могу изменить структуру базы данных.

Это очень сложная вещь, я боюсь, что вы не поймете, что мне нужно. Я надеюсь, что SQLFiddle поможет. И если у вас есть еще вопросы, пожалуйста, спросите меня.

Итак, учитывая, что мое решение, мой запрос не работает из-за сбоя базы данных, если я его запускаю. Есть ли способ получить желаемый результат? Могу ли я как-то оптимизировать этот запрос, или мне нужно написать какой-то другой, или сделать что-то еще? Я довольно растерялся, так как мне никогда не приходилось углубляться и читать данные из такого количества таблиц только для того, чтобы получить желаемый результат.

Спасибо, Анита


person Anita    schedule 26.02.2015    source источник


Ответы (2)


Кажется, это то же самое:

SELECT DISTINCT company_report.* 
FROM company_report, 
     company, 
     users, 
     club, 
     club_offer, 
     club_offer_cpv  
WHERE company_report.company_special_id = company.special_id AND 
      company.id = users.company_id AND
      users.id = club.users_id AND
      club.id = club_offer.club_id AND
      club_offer.id = club_offer_id AND
      club_offer_cpv.cpv_id = 66113000

Другие люди предпочтут объединения, но я считаю, что это легче читать, и они эквивалентны. Это будет выглядеть примерно так:

SELECT DISTINCT company_report.* 
FROM company_report
JOIN company        ON company_report.company_special_id = company.special_id 
JOIN users          ON company.id = users.company_id 
JOIN club           ON users.id = club.users_id
JOIN club_offer     ON club.id = club_offer.club_id
JOIN club_offer_cpv ON club_offer.id = club_offer_id AND
                       club_offer_cpv.cpv_id = 66113000   

На самом деле, это неплохо, я имею в виду, что я мог бы даже предпочесть этот последний.

person KIKO Software    schedule 26.02.2015
comment
Я бы именно так и сделал. Единственное, что я бы добавил, это использование EXPLAIN MySQL. в случае, если это все еще занимает вечность, так как, вероятно, существует сломанный или несуществующий индекс (ы). - person Patrick Webster; 26.02.2015
comment
Да, вам нужна правильная индексация. Кажется, он отлично работает в SQLFiddle. - person KIKO Software; 26.02.2015
comment
Спасибо всем, я попробую эти решения завтра на рабочем сервере с реальной базой данных, надеюсь, это сработает. Пожелай мне удачи :D - person Anita; 27.02.2015
comment
Я расширил этот вопрос новыми запросами. Не могли бы вы проверить это? stackoverflow.com/questions/28794767/ Спасибо. - person Anita; 01.03.2015

Добавьте индекс к идентификаторам отношений между таблицами, затем попробуйте добавить одну за другой таблицу, используя левые внешние соединения.

person Juan    schedule 26.02.2015