Ускорить выбор из нескольких таблиц

#php #mysql #sql #select

#php #mysql #sql #выберите

Вопрос:

Мне нужно ускорить sql-запрос. Или лучше обрабатывать php-код. Некоторые рекомендации при поиске в базе данных и отображении результата во внешнем интерфейсе.

В принципе, у меня есть три таблицы — поля, которые содержат записи — записи, которые содержат песни — песня

Я бы хотел, чтобы в моем интерфейсном коде было что-то вроде:

 Box 1
 -Record 1
  --Song 1
  --Song 2
    etc....
 -Record 2
  --Song 1
  --Song 2
    etc....
Box 2
 -Record 1
  --Song 1
  --Song 1
etc. etc. etc.
 

«Мой путь» занимает очень много времени:

  1. Я ищу таблицу «Box», используя стандартный SQL.
  2. Для каждой строки я вызываю функцию, которая находит каждую запись для этого поля
  3. Для каждой записи я вызываю функцию, которая находит каждую песню для этой записи

Для завершения требуется много времени, поскольку количество вызовов select огромно (много полей, много записей)

Я думаю, есть более простой способ (с точки зрения серверов) сделать то же самое. Потяните dato к массивам php и к логике там или что-то еще, что умно.

Вопрос: Как лучше всего получать данные из реляционной базы данных с использованием php?

Br. Андерс

Комментарии:

1. Хаммерайт прав. Вы должны использовать объединения, таким образом, вам нужно выполнить только один запрос, который будет намного быстрее, чем ваш текущий подход. Кроме того, вы можете использовать первичные и внешние ключи или индексированные столбцы для вашего пути соединения, чтобы еще больше увеличить скорость вашего запроса.

Ответ №1:

Вам нужно узнать о JOIN s. Здесь вы должны использовать два внешних соединения. Таким образом, вы достигаете того же результата, используя только один запрос select, и объем работы, который должен быть выполнен PHP и MySQL, намного меньше.

Ваш SQL будет выглядеть примерно так: (Обратите внимание, что я использую SELECT * в качестве дублера для реального списка столбцов, потому что я не знаю, какие столбцы у вас есть — использование SELECT * , как правило, не очень хорошая идея)

 SELECT
    *
FROM
    Box
    LEFT JOIN Record ON Box.BoxID = Record.BoxID
    LEFT JOIN Song ON Record.RecordID = Song.RecordID
 

Комментарии:

1. 1 для левых соединений, что позволяет выбирать поля без записей 🙂

2. Спасибо. Но я не знаю, как получить из инструкции sql с помощью join для отображения данных на веб-сайте. Так что, возможно, это скорее вопрос php, чем вопрос sql

3. Вам просто нужно использовать цикл, как вы уже делали. Возможно, используйте переменные для отслеживания того, когда вы перешли к следующей записи / следующему блоку, поскольку тогда вы можете захотеть отразить это в отображаемых данных.

4. Да. Внезапно это имеет смысл. Я могу извлечь дату с помощью объединений и сохранить ее в массиве в php. Затем запустите массив для создания выходных данных. Спасибо

Ответ №2:

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

вы достигаете этого, используя объединения, см.: http://en.wikipedia.org/wiki/Join_ (SQL)

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

 SELECT s.* FROM box b
INNER JOIN record r ON r.box_id = b.box_id
INNER JOIN song s ON s.record_id = r.record_id
WHERE box.name = 'mybox'
 

будет быстрее, чем:

 select from box b
   where box.name = 'mybox'
LOOP
  select record_id from record 
  LOOP
      select * from song
  END 
END
 

Комментарии:

1. Вы должны использовать «левое соединение» вместо «внутреннего соединения», которое затем позволит выбирать поля без записей. Выше будут отображаться только поля, содержащие записи. Пример см. В ответе @Hammerite.

2. если бы в поле «mybox» не было записей, то ваше поле возвращало бы нулевые строки, использование «левого соединения» возвращало бы одну строку, содержащую тот факт, что поле «mybox» действительно существует, даже если в нем нет записей.

3. Достаточно справедливо 😉 Мне все равно было бы интересно узнать, в каких полях не было записей. Раньше у меня были случаи, когда мне нужно было показывать все элементы в первой таблице, даже если их нет в последующих объединенных таблицах. Да, я думаю, что это было бы скорее проблемой пользовательского интерфейса, возможно, как в списке контактов, где у вас может не быть контактов, например, в разделе «Q», но вы все равно хотите показать заголовок … 🙂