Переписать запрос, чтобы удалить FIND_IN_SET? - PullRequest
2 голосов
/ 04 июня 2010

Мой запрос MySQL выглядит так:

    SELECT pages.*,
           showcase.*,
           project.*    
      FROM pages
INNER JOIN showcase ON showcase.pid = pages.uid AND showcase.deleted != 1
INNER JOIN project ON FIND_IN_SET(project.uid, showcase.projects)   
     WHERE pages.deleted != 1
       AND pages.pid = 14
       AND pages.dokType = 150

Проблема вторая INNER JOIN - она ​​использует FIND_IN_SET, поскольку витрина (= коллекция проектов) сохраняет свои проекты в виде списка через запятую в поле showcase.projects. Насколько мне известно, FIND_IN_SET не может использовать индексы, поэтому для второго соединения требуется полная проверка таблицы проекта. Любая возможность использовать индекс без изменения схемы базы данных?

Ответы [ 2 ]

0 голосов
/ 04 июня 2010

Вы ищете «строку» внутри другой строки. Вы должны сделать сканирование независимо. Другой оптимизированный способ сделать это с помощью индексов - это использовать таблицу соединений. Создайте новую таблицу showcase_projects со столбцами project_id и showcase_id. Затем будет запись для каждой ассоциации между ними.

Теперь этот ответ основан на моем примитивном понимании вашей структуры данных из этого запроса.

0 голосов
/ 04 июня 2010

Является ли showcase.projects a VARCHAR? Тогда вы можете использовать REGEXP так:

...
INNER JOIN project ON
showcase.projects REGEXP CONCAT('[[:<:]]', project.uid, '[[:>:]]')
WHERE ...

Это выражение ищет только целые слова (конструкции в скобках отмечают границы слов слева и справа соответственно. Однако я не уверен, что он сможет использовать индекс, возможно, кто-то может придумать что-нибудь умнее.

...