MySQL CONCAT '*' символ тосты базы данных

У меня есть таблица, используемая для поиска, в которой в одном столбце хранится удобочитаемое значение, а в другом - тот же текст без специальных символов и пробелов. Например, значение "Детские шоу" будет отображаться в столбце поиска как "детские шоу".

К сожалению, соответствующая основная таблица не так проста - по историческим причинам я не создавал себя и теперь было бы трудно отменить, значение поиска на самом деле хранится с окружающими звездочками, например, "* childrens-shows *".

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

    SELECT * 
      FROM main_table m 
INNER JOIN lookup_table l 
        ON l.value = CONCAT('*',m.value,'*')

... а затем стол был тост. Не уверен, создал ли я бесконечный цикл или действительно испортил данные, но мне потребовалась резервная копия ISP, чтобы таблица снова ответила. Я подозреваю, что это потому, что символ '*', вероятно, зарезервирован, как подстановочный знак, и я попросил базу данных сделать эквивалент облизывания собственного локтя. В любом случае, я не решаюсь "поэкспериментировать", чтобы найти ответ, учитывая то, как ему удалось убить базу данных.

Заранее спасибо всем, кто может (а) рассказать мне, что на самом деле было сделано с базой данных, и (б) как мне на самом деле присоединиться к таблицам?

1 ответ

Решение

При использовании CONCAT mysql не будет использовать индекс. Используйте EXPLAIN, чтобы проверить это, но недавняя проблема, с которой я столкнулся, заключалась в том, что на большой таблице был индексированный столбец, но ключ не использовался. Это не должно мешать всей таблице, просто сделайте это медленно. Возможно, ему не хватило памяти, он начал обмениваться, а затем рухнул на полпути, но вам нужно проверить журналы, чтобы выяснить это.

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

Лучшее решение - переместить эти данные в отдельную таблицу. "Детские шоу" звучит как категория и поэтому повторяет данные во многих строках. Это действительно должен быть идентификатор для таблицы "категорий", что помешало бы БД запускать CONCAT для каждой отдельной строки таблицы, как вы могли бы сделать это:

    SELECT * 
      FROM main_table m 
INNER JOIN lookup_table l 
        ON l.value = m.value
   /* and optionally */
INNER JOIN categories cat
        ON l.value = cat.id
     WHERE cat.name = 'whatever'

Я знаю, что это не то, что вы можете сделать, учитывая информацию, которую вы указали в своем вопросе, но на самом деле причина, по которой вы не можете внести такое изменение в плохо нормализованную БД, более важна, чем приведенный здесь код. Без ресурсов или политической поддержки, чтобы сделать все правильно, у вас будет еще больше таких головных болей, которые в конечном итоге будут стоить дороже. Пора поговорить с боссом пожалуй:)

Другие вопросы по тегам