У меня проблема с настройкой webapp, для которой я разработал одно решение, но пытаюсь найти другие идеи, которые могут затронуть некоторые проблемы производительности, которые я вижу.
постановка задачи:
То, что я хочу сделать, но не понял, состоит в том, чтобы отправить 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 и получают результаты. С помощью этого метода это происходит один раз, а не один раз за токен, поэтому производительность будет возрастать, я просто не знаю, будет ли это достаточно.
Я знаю, что это не является строго ответом на вопрос, который вы задаете, но если ваша таблица – это тысячи, а не миллионы строк , то решение FULLTEXT может быть лучшим способом пойти сюда.
В MySQL, когда вы используете MATCH в индексированном столбце, каждому указанному вами ключевому слову присваивается рейтинг релевантности (рассчитывается примерно по количеству раз, когда упоминалось каждое ключевое слово), который будет более точным, чем ваш метод, и, безусловно, более эффективен для нескольких ключевых слов.
См. Здесь: http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
Если вы используете шаблон UNION ALL, вы также можете включить в свой запрос следующие части:
SELECT COUNT(*) AS C ... GROUP BY ID ORDER BY c DESC
Хотя это действительно тривиальный пример, он дает вам частоту совпадений для каждого результата, и для начала это может быть псевдо-ранг.
Вероятно, вы получите гораздо лучшую производительность, если бы использовали структуру данных, предназначенную для задач поиска, а не для базы данных. Например, вы можете попробовать создать инвертированный индекс . Однако, вместо того, чтобы писать это самостоятельно, вам также может понадобиться посмотреть на что-то вроде Lucene, которое делает большую часть работы для вас.