mysql оптимизирует или упрощает операторы SQL

#mysql

Вопрос:

таблица mysql является

запись пересечения основная информация

связь запись пересечения и отношения на обочине, пересечения и отношения на пересечении

код

 SELECT c.*,  d.obj_name as end_name,  e.obj_name as start_name  from ( SELECT a.source_key as start_key,  b.source_key as end_key,  a.target_key as roadside_key  FROM ( SELECT *  FROM `brelation`  WHERE source_key='c1_VbFljpol'  and target_concept='roadside'  and rel_number=1  ) as a  JOIN ( SELECT *  FROM `brelation`  WHERE source_key in (  SELECT target_key  FROM `brelation`  WHERE source_key='c1_VbFljpol'  and target_concept='node'  )  and target_concept='roadside边'  and rel_number=2  ) as b ON a.target_key=b.target_key   ) as c  JOIN bintersection as d ON c.end_key=d.obj_key  JOIN bintersection as e ON c.start_key=e.obj_key  

окончательное решение

 start_key start_name end_key roadside_key end_name c1_VbFljpol aaaa c1_hKwEo6JZ c3_G2rSzUIK bbbb c1_VbFljpol aaaa c1_gDUWuB4V c3_YtKWzPy0 cccc c1_VbFljpol aaaa c1_uayODvZz c3_SMz1WGl0 dddd  

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

1. Ты зашел слишком далеко. Каково нынешнее поведение с этим? Как определяются таблицы? Что это explain показывает? Правильный ли возврат просто занимает слишком много времени?

Ответ №1:

Вау… что за дурацкий вопрос.. Однако, когда вы переписываете, это ли то, что вы в конечном итоге ищете?

 SELECT   br.source_key Start_Key,  br2.source_key End_Key,  br.target_key Roadside_Key,  bi2.obj_name as end_name,  bi.obj_name as start_name   FROM   brelation br  JOIN bintersection as bi  ON br.source_key = bi.obj_key   JOIN brelation br2  on br.target_key = br2.target_key  AND br.source_key = br2.source_key  AND br2.target_concept = 'node'  AND br2.rel_number = 2   JOIN bintersection as bi2  ON br2.source_key = bi2.obj_key  WHERE  br.source_key = 'c1_VbFljpol'   and br.target_concept = 'roadside'   and br.rel_number = 1  

Ваши внутренние запросы подзапросов, создающие псевдонимы A и B, нацелены на один и тот же источник, но «rel_number» = 1 и Придорожный по сравнению с «rel_number» = 2 и узлом. Так что просто присоединяйтесь к тем, кто они есть. Теперь ваши таблицы разделов. Я также использую их с соответствующими псевдонимами от BR/BI до BR2/BI2 соответственно для начального и конечного контекста.

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

Я ДУМАЮ, что это то, что вы ищете.

Отзывы

О производительности ничего не говорилось… Для этого и зная, что предоставленный запрос более чистый и делает то, что вам нужно, теперь мы можем посмотреть на индексы. Для этого запроса я бы предложил правильный многоколоночный индекс для таблиц следующим образом.

 table Index brelation (Source_Key, Target_Concept, Rel_Number) bintersection (Obj_Key, obj_name)  

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

1. тогда улучшилась читаемость,но скорость не сильно улучшилась, возможно, что объем данных недостаточно велик

2. @xin.chen, смотрите отзывы в ответе для получения надлежащих показателей производительности.

Ответ №2:

* Замените только те столбцы, которые вам нужны.

Превратиться source_key in ( SELECT ... ) в JOIN или EXISTS ( SELECT 1 ...)

Если вы не используете MySQL 8.0, эта конструкция, скорее всего, будет медленной:

 FROM ( SELECT ... ) a JOIN ( SELECT ... ) b ON ...  

(Я не понимаю, что запрос будет достаточно, чтобы предложить переписать.)

Индексы, которые могут помочь:

 bintersection: INDEX(obj_key, obj_name) brelation: INDEX(source_key, target_concept, rel_number, target_key) brelation: INDEX(target_concept, rel_number, source_key) brelation: INDEX(source_key, target_concept)  

Это может помочь переписать Драппа, возможно, этот индекс тоже понадобится:

 brelation: INDEX(target_key, source_key, target_concept, rel_number)