2013-02-11 3 views
1

У меня есть функция «fnc_FindIssueId», которая принимает идентификатор объекта и возвращает его присвоенный идентификатор проблемы.Как использовать SQL-функцию с INNER JOIN в MySQL?

Когда я вызываю функцию с использованием чистых операторов выбора, она отлично работает:

select fnc_FindIssueId(150083); // returns 1 as issueId for objectId of 150083 
select fnc_FindIssueId(150072); // returns 2 as issueId for objectId of 150072 

Но когда я использую его в качестве внутреннего соединения, он переходит в нескончаемом цикле:

select so.id, si.id 
from smart_objects as so 
     LEFT OUTER join smart_issues as si 
     on si.id = fnc_FindIssueId(so.id) 
where so.id in (150083, 150072); 

В чем причина и как его решить?

+0

Ваш второй пример: ** OUTER ** join, а не * INNER * join. –

ответ

1

не выполняет нескончаемый цикл.

Причина этого в том, что сервер выполняет FULL TABLE SCAN, что очень медленно. Это условие si.id = fnc_FindIssueId(so.id) не использует индекс, даже если вы определили его на si.id и so.id.

Лучшие способы вы можете сделать это:

  • , чтобы изменить таблицу smart_objects
  • еще один столбец для assigned issue Id
  • определить индекс на новый столбец
+0

Логика поиска идентификатора проблемы сложна и зависит от некоторых других сценариев, поэтому была создана отдельная функция. Я не могу изменить дизайн, пожалуйста, ответьте на вопрос, можете ли вы, спасибо. –

+0

Почему он выполняет сканирование полного стола ?! Я добавил фильтры в предложение WHERE, чтобы ограничить их? Он должен применить фильтр, а затем присоединиться, подобно SQL Server! –

+0

Это лучший ответ, который я могу сказать. Может быть, другие могут. Я не могу помочь вам оптимизировать запрос, потому что вы присоединяетесь к результату функции. –

0

Обойти было для создания нового представления с столбцами ObjectId и IssueId, а затем вызова этой функции изнутри этого представления! но теперь он стал очень медленным.

CREATE ALGORITHM=UNDEFINED DEFINER=`mysql`@`%` SQL SECURITY DEFINER VIEW `vw_smart_objectissue` AS select `so`.`id` AS `objectid`,`fnc_FindIssueId`(`so`.`id`) AS `issueid` from `smart_objects` `so` order by `so`.`id`$$