У меня есть проблема разработки веб-приложений, для которой я разработал одно решение, но я пытаюсь найти другие идеи, которые могут обойти некоторые проблемы с производительностью, которые я вижу.
постановка задачи:
Что я хочу сделать, но не понял, так это отправить 1 запрос, который возвращает что-то похожее на результаты in (), но возвращает повторяющийся идентификатор записи для каждого совпадения токена для каждого проверенного идентификатора записи.
Есть ли лучший способ сделать это, чем то, что я делаю, - использовать несколько отдельных запросов, выполняющих один запрос на токен? Если да, то как проще всего их реализовать?
редактировать
Я уже токенизировал записи, поэтому, например, "see spot run" имеет идентификатор записи 1 и три токена, 'see', 'spot', 'run', и они находятся в отдельной таблице токенов, с соответствующими идентификаторами записей, поэтому таблица может выглядеть так:
'see', 1
'spot', 1
'run', 1
'run', 2
'spot', 3






вы можете добиться этого за один запрос, используя «UNION ALL» в MySQL.
Просто прокрутите токены в PHP, создав UNION ALL для каждого токена:
например, если токены 'x', 'y' и 'z', ваш запрос может выглядеть примерно так
SELECT * FROM `entries`
WHERE token like "%x%" union all
SELECT * FROM `entries`
WHERE token like "%y%" union all
SELECT * FROM `entries`
WHERE token like "%z%" ORDER BY score ect...
Предложение order должно работать со всем набором результатов как с одним, что вам и нужно.
С точки зрения производительности это будет не так уж и быстро (я предполагаю), однако с базами данных основные накладные расходы с точки зрения скорости часто связаны с отправкой запроса к ядру базы данных из PHP и получением результатов. С помощью этого метода это происходит только один раз, а не один раз на токен, поэтому производительность увеличится, я просто не знаю, будет ли этого достаточно.
Просто не забудьте использовать UNION ALL, а не только UNION, иначе я не думаю, что вы получите несколько строк, возвращенных с тем же идентификатором, как вы хотите. - rmbarnes 06 сен.
Если вы используете шаблон UNION ALL, вы также можете включить в свой запрос следующие части:
SELECT COUNT(*) AS C
...
GROUP BY ID
ORDER BY c DESC
Хотя это действительно тривиальный пример, он дает вам частоту совпадений для каждого результата, и это может быть псевдо-ранг для начала.
Вероятно, вы получите гораздо лучшую производительность, если будете использовать структуру данных, предназначенную для задач поиска, а не базу данных. Например, вы можете попробовать построить инвертированный индекс. Однако вместо того, чтобы писать это самостоятельно, вы можете также изучить что-то вроде Lucene, которое выполняет большую часть работы за вас.
Я знаю, что это не совсем ответ на вопрос, который вы задаете но если ваша таблица состоит из тысяч, а не миллионов строк, тогда решение FULLTEXT может быть лучшим способом здесь.
В MySQL, когда вы используете MATCH в своем индексированном столбце, каждому ключевому слову, которое вы вводите, будет присвоена оценка релевантности (рассчитанная примерно по количеству упоминаний каждого ключевого слова), которая будет более точной, чем ваш метод, и, безусловно, более эффективной для нескольких ключевых слов.
Глянь сюда: http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
@rmbarnes - должно быть, именно здесь те операции UNION, которые я видел в db basics много лет назад, внезапно обретают смысл; Я обязательно проверим его производительность, чтобы увидеть, как он сравнивается с общей скоростью.