неужели вложенный запрос вычисляется каждый раз, для каждой новой строки? Да даже если и так, не может это повесить базу. Пример. Есть таблица city [sql]id | pid| name[/sql] pid - id страны есть street [sql]id | pid | name[/sql] pid - id города есть area (районы города) [sql]id | pid | name[/sql] pid - id города и таблица area_street (улица - район) [sql]id | area | street[/sql] так вот, предположим нужны вывести все улицы определённого района города одним запросом. Упростим, без фильтра по городу беру, так как уже в принципе район привязан к городу и один район не будет в разных городах. [sql]SELECT * FROM `street` WHERE `id` IN ( SELECT GROUP_CONCAT(`street`) FROM `area_street` WHERE `area` = 1 );[/sql] Этот запрос ждал минуту, при всём при этом в базе всего 70 000 улиц. В районе 1 - 12 улиц. Берём зарпос [sql]SELECT GROUP_CONCAT(`street`) FROM `area_street` WHERE `area` = 1;[/sql] результат [sql]1,2,3,4,5,6,7,8,9,10,11,12[/sql] Выводит мгновенно, не засекал время, но вообще не виснет, ну и с чего бы виснуть такому запросу. теперь берём подставляем [sql]SELECT * FROM `street` WHERE `id` IN ( 1,2,3,4,5,6,7,8,9,10,11,12 );[/sql] Выводит 12 улиц, тоже мгновенно Почему вместе виснет? Ждал минуту, нагрузка на проц 100% проц атлон 5600+ Приходится отрубать службу. Я понимаю что можно сделать так [sql]SELECT `street`.* FROM `street`, `area_street` WHERE `street`.`id` = `street` AND `area` = 1;[/sql] И будет выведено 12 улиц, но вопрос именно про вложенный запрос, так как на сайте MySQL читал что с версии 4.1 кажется или раньше, запросы вложенные идентичны запросу с объединением, но что то разница очень велика Так как база не моя, я просто брал дамп заливал и испытывал, потом создал индексы для полей `area_street`.`area` и `street`.`id` запрос стал выполнятся около 4х секунд и возвращать только одну улицу. где я ошибаюсь с вложенным запросом, почему зависает и работает не так как задумано?
это что за порнография? GROUP_CONCAT возвращает строку, которая используется в IN( как одно значение. надо возвращать набор данных. Но в любом случае для вашей задачи (и этой и других возможных) вам не нужны вложенные запросы. Пишите нормальные JOIN'ы.
мне для задачи как раз нужен был именно вложенный запрос, так как мне в класс нужно было передавать только массив который потом объединится во что то похожее на WHERE ' . implode(' AND ', $where); по этому я и написал $where[] = "`id` IN ( SELECT GROUP_CONCAT(`street`) FROM `area_street` WHERE `area` = 1 )"; у меня 2 варианта, либо сделать вложенный, либо сделать вначале отдельно [sql] SELECT GROUP_CONCAT(`street`) FROM `area_street` WHERE `area` = 1[/sql] а потом уже его отправить параметром я сделал 2 запроса, так как со вложенным не вышло
интересно так [sql]SELECT * FROM `street` WHERE `id` IN ( SELECT `street` FROM `area_street` WHERE `area` = 1 ) limit 12;[/sql] всё работает и с любым числом меньше 12 а вот если написать 13 то виснет.