Что является более эффективным: SQL JOIN или вложенный цикл PHP? - PullRequest
2 голосов
/ 26 августа 2011

У меня есть несколько таблиц, из которых мне нужно отобразить данные.

Schools
-------
id | Title

Programs
--------
id | descr | title | type | school.id

Конечно, не самая лучшая настройка, но я ничего не могу поделать со структурой базы данных.

Мне нужно создать список, разделенный по школе, программе и типу программы. Прямо сейчас у меня есть большой огромный вложенный цикл (псевдокод):

Select * from Schools
For Each School
    print $school_header;
    Select Program Type from Programs WHERE School.id = $school_id 
        For Each Program type
           print $type_header;
           Select * from Programs where School.id = $school_id and type = $program_type
           For Each Program
               print $program_link;

Излишне говорить, что это большой беспорядок.

Конечным результатом является список:

  • Программа 1
    • Тип программы 1
      • Программа
      • Программа
    • Тип программы 2
      • Программа
      • Программа
    • Тип программы 3
      • Программа

Есть ли способ сделать это с меньшим количеством запросов и меньшим количеством кода, который не так интенсивно использует базу данных?

Ответы [ 4 ]

5 голосов
/ 26 августа 2011

Реальная проблема здесь не в том, является ли один или другой язык программирования более эффективным.Огромная, огромная разница в производительности обусловлена ​​локальностью данных, а именно тем, что для выполнения запроса к самой базе данных не требуется перемещать все данные назад и вперед по проводам для оценки, в то время как решение PHP делает это.

Для вашего запроса вам нужно написать хранимую процедуру, которая возвращает несколько наборов результатов (для дальнейшего объединения в PHP) или один большой набор результатов (путем объединения в SQL).Я думаю, что это будет выглядеть примерно так:

SELECT S.Title as School_Title, pt.title as Program_type_title, p.title as Program_Title
FROM School S 
INNER JOIN ProgramType pt on s.id = pt.school_id
INNER JOIN Program p on pt.id = p.program_type_id
ORDER BY S.Title, pt.title, p.title

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

3 голосов
/ 26 августа 2011

MSSQL сделает намного лучше. Это то, как СУБД предназначены для обработки такого рода вещей. Если вы делаете их на сервере БД, вы экономите свое использование сети.

1 голос
/ 26 августа 2011

MSSQL предназначен для выполнения объединений.Более того, если повезет, ваши таблицы могут быть проиндексированы, что еще больше увеличит производительность.

(весьма вероятно) всегда лучше выполнить сложный запрос, чем зацикливать все данные с помощью php.

РЕДАКТИРОВАТЬ:

Возможно, вы можете использовать псевдонимы для маркировки структуры данных.
Пример: SELECT id as test_id .... SELECT program as test_test2_program... и т. Д.

0 голосов
/ 26 августа 2011
SELECT *
FROM Schools
INNER JOIN Programs
    ON Programs."school.id" = Schools.id
INNER JOIN Groups
    ON Groups."programs.id" = Programs.id
INNER JOIN GroupsToCourses
    ON GroupsToCourses.group_id = Groups.id
INNER JOIN Courses
    ON Courses.course_id = GroupsToCourses.course_id

Он почти наверняка превзойдет ваш код в PHP и может значительно превзойти его, сохранив циклические обращения к базе данных, данные по проводам, а также позволив оптимизатору базы данных сделать свое дело.

...