В компании, где я работал, они работают с реляционной базой данных PHP / MySQL. Я всегда думал, что если бы мне нужно было извлечь различную информацию из разных таблиц, то я мог бы просто сделать простое объединение, чтобы получить такие данные, как ....
SELECT table_1.id, table_2.id FROM table_1 LEFT JOIN table_2 ON table_1.sub_id = table_2.id
Когда я попал туда, где я сейчас работаю, это то, что они делают.
<?php $query = mysql_query("SELECT sub_id FROM table_1");
while($rs = mysql_fetch_assoc($query)) {
$query_2 = mysql_fetch_assoc(mysql_query("SELECT * FROM table_2 WHERE id = '{$rs['sub_id']}'"));
//blah blah blah more queries
?>
Когда я спросил, почему он сделал это вторым способом, они сказали, что на самом деле он работает быстрее, чем объединение. Они управляют базой данных, в которой миллионы записей в разных таблицах, а некоторые таблицы немного широки (по строкам). Они сказали, что хотят избежать объединений в случае, если плохо выполненный запрос может заблокировать таблицу (или несколько из них). Еще одна вещь, которую нужно иметь в виду, это то, что к этой базе данных подключен массивный построитель отчетов, который клиент может использовать для создания своего собственного отчета, и если он сходит с ума и создает большой отчет, это может вызвать некоторый хаос.
Я был сбит с толку, поэтому подумал, что выложу это для широкой публики. Это может быть вопросом мнения, но действительно ли быстрее сделать оператор while (один больший запрос, чтобы вытащить много строк, а затем, если хотите, множество маленьких крошечных подзапросов) или выполнить объединение (тянуть один запрос большего размера, чтобы получить все необходимые данные). Пока индексы сделаны правильно, имеет ли это значение? Еще одна вещь, которую следует учитывать, это то, что текущая БД находится в формате InnoDB.
Спасибо!
Обновление 8/28/14
Так что я подумал, что добавлю обновление и то, что работало более долгое время. После этого обсуждения я решил перестроить генератор отчетов здесь, на работе. У меня нет точных результатов, но я решил поделиться результатами.
Я думаю, что это было немного излишним, потому что я превратил весь отчет (он довольно динамичен в отношении возвращаемых данных) в масштабный фестиваль объединения. Большинство соединений, если не все, объединяют значение с первичным ключом, поэтому все они выполняются очень быстро. Если в отчете было указано, что нужно извлечь 30 столбцов данных, а в 2000 записей, то в каждом поле выполнялся запрос для извлечения данных (поскольку этот фрагмент данных мог находиться в другом поле). 30 x 2000 = 60000 и даже при приятном времени запроса 0,0003 секунды на запрос, это все равно было 18 секундами простого времени запроса (что, как я помню, довольно много). Теперь, когда я перестроил запрос как массивное объединение нескольких первичных ключей (где это возможно), этот же отчет загружался примерно через 2-3 секунды, и большую часть этого времени загружал html. Каждая возвращаемая запись выполняет от 0 до 4 дополнительных запросов в зависимости от необходимых данных (может не потребоваться никаких данных, если они могут извлечь их в объединениях, что происходит в 75% случаев). Таким образом, те же самые записи 2000 будут возвращать дополнительные 0-8000 запросов (намного лучше, чем 60000).
Я бы сказал, что оператор while полезен в некоторых случаях, но, как указано ниже в комментариях, это все, что касается тестирования. В моем случае, объединения были лучшим вариантом, но в других областях моего сайта, инструкция while более полезна. В одном случае у меня есть отчет, в котором клиент может запросить несколько категорий и получить только данные для этих категорий. Случилось так, что у меня был category_id IN(...,...,..,.., etc etc etc)
с 50-500 удостоверениями личности, и индекс захлебывался и умирал в моих руках, когда я держал его в последние минуты. Поэтому я разложил идентификаторы по группам по 10 и выполнил один и тот же запрос x / 10 раз, и мои результаты были получены в раз быстрее, чем раньше, потому что индекс любит работать с 10 идентификаторами, а не 500, поэтому Тогда я увидел значительное улучшение в моих запросах благодаря выполнению оператора while.