MYSQL: как правильно использовать внешние псевдонимы в подзапросе?

Первый запрос работает нормально. Он возвращает одну строку из таблицы «точка маршрута». У него есть определенный 'route_id', а 'geo_distance ()' находится на минимальном уровне с учетом параметров. Я знаю, что подзапрос в разделе FROM кажется излишне сложным, но, на мой взгляд, он помогает выявить проблему со вторым запросом.

Отличия указаны в последних двух строках.

SELECT rp.*

FROM routepoint rp, route r, (SELECT * FROM ride_offer WHERE id = 6) as ro

WHERE rp.route_id = r.id
AND r.id = ro.current_route_id
AND geo_distance(rp.lat,rp.lng,52372070,9735690) = 

(SELECT MIN(geo_distance(lat,lng,52372070,9735690)) 
FROM routepoint rp1, ride_offer ro1 
WHERE rp1.route_id = ro1.current_route_id AND ro1.id = 6);

Следующий запрос вообще не работает. Он полностью замораживает mysql, и мне приходится перезапускать его. Что я делаю неправильно? Первый подзапрос возвращает ровно одну строку. Я не понимаю разницы.

SELECT rp.*

FROM routepoint rp, route r, (SELECT * FROM ride_offer WHERE id = 6) as ro

WHERE 
rp.route_id = r.id
AND r.id = ro.current_route_id
AND geo_distance(rp.lat,rp.lng,52372070,9735690) = 

(SELECT MIN(geo_distance(lat,lng,52372070,9735690)) 
FROM routepoint rp1 
WHERE rp1.route_id = ro.current_route_id);

person Nielow    schedule 03.10.2011    source источник
comment
Насколько велика таблица точек маршрута? Кроме того, сравнивали ли вы план выполнения двух операторов?   -  person Klas Lindbäck    schedule 03.10.2011
comment
Вы пытаетесь написать зависимый подзапрос - подзапрос будет выполняться один раз для каждой строки набора результатов внешнего запроса, и это будет ужасно медленным, если у вас много строк - вы захотите оптимизировать свой подзапрос настолько, насколько вы можете.   -  person Romain    schedule 03.10.2011
comment
@Klas в таблице точек маршрута около 14 тыс. Строк, и она станет намного больше.   -  person Nielow    schedule 03.10.2011
comment
@Romain, какой это результат? Каждая комбинация из 3 таблиц или каждая комбинация, соответствующая предыдущим предложениям WHERE?   -  person Nielow    schedule 03.10.2011
comment
@Nielow MySQL сначала применит все фильтры, которые не требуют выполнения зависимого подзапроса. Если на этом этапе предикат по-прежнему TRUE, то подзапрос будет оценен. Однако это может испортить некоторые уровни оптимизации - mysql не очень хорош в зависимых подзапросах.   -  person Romain    schedule 03.10.2011
comment
Синтаксис неявного соединения был определен в SQL '89. Его заменяет явный синтаксис соединения SQL '92. С тех пор неявное соединение является анти-шаблоном, потому что слишком легко выполнять случайные перекрестные соединения и трудно увидеть критерии соединения между всеми остальными предложениями where.   -  person Johan    schedule 03.10.2011


Ответы (1)


Проблема, как указал Ромен, в том, что это дорого.

В этой статье описывается алгоритм, который снижает стоимость на 2 пошаговый процесс.

Шаг 1. Найдите ограничивающую рамку, содержащую хотя бы одну точку.

Шаг 2: Найдите ближайшую точку, изучив все точки в ограничивающей рамке, число которых должно быть сравнительно небольшим, а значит, не таким дорогостоящим.

person Klas Lindbäck    schedule 03.10.2011