#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.
«Мой путь» занимает очень много времени:
- Я ищу таблицу «Box», используя стандартный SQL.
- Для каждой строки я вызываю функцию, которая находит каждую запись для этого поля
- Для каждой записи я вызываю функцию, которая находит каждую песню для этой записи
Для завершения требуется много времени, поскольку количество вызовов 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», но вы все равно хотите показать заголовок … 🙂