2010-06-04 2 views
2

Моего MySQL запрос выглядит следующим образом:Перезаписывающий запрос для удаления FIND_IN_SET?

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 Невозможно использовать индексы, насколько мне известно, поэтому для второго соединения требуется полное сканирование таблицы проекта. Любая возможность использовать индекс без изменения схемы базы данных?

ответ

0

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

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

+0

Угадайте, что вы правы, я начну нормализовать данные в понедельник. Конечно, лучшее решение. – Max

+0

Удачи. Просто не уходите от дезадаптации к нормализации :) Это может привести к повышению производительности/решению проблем данных в будущем. –

0

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

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

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

Смежные вопросы