которая делает большую часть работы для вас.

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

постановка задачи:

пользователь вводит несколько ключевых слов / токеновприложение ищет совпадения с токенаминужен один результат для каждого токенато есть, если в записи 3 токена, мне нужен идентификатор входа 3 разаранжировать результатыназначить X очков за совпадение токенасортировать идентификаторы записей на основе точекесли значения точек совпадают, используйте дату для сортировки результатов

То, что я хочу сделать, но не выяснил, это отправить 1 запрос, который возвращает что-то похожее на результаты in (), но возвращает дублированный идентификатор записи для каждого совпадения токена для каждого проверенного идентификатора записи.

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

редактировать
Я уже разбил токены на записи, так что, например, «see spot run» имеет идентификатор записи 1 и три токена, «see», «spot», «run», и они находятся в отдельной таблице токенов, с соответствующими им идентификаторами записей, поэтому таблица может выглядеть так:

'see', 1 
'spot', 1 
'run', 1 
'run', 2 
'spot', 3 

Ответы на вопрос(4)

но если ваша таблица тысяч, а не миллионов строк, тогда решение FULLTEXT может быть лучшим способом.

В MySQL, когда вы используете MATCH для своего индексированного столбца, каждому ключевому слову, которое вы предоставляете, будет присвоен показатель релевантности (рассчитанный примерно по числу упоминаний каждого ключевого слова), который будет более точным, чем ваш метод, и, безусловно, более эффективным для нескольких ключевых слов.

Глянь сюда:http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

Решение Вопроса

используя «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...

Предложение порядка должно работать со всем результирующим набором как единым, что вам и нужно.

С точки зрения производительности это будет не так быстро (я предполагаю), однако в случае с базами данных основная нагрузка с точки зрения скорости часто заключается в отправке запроса в ядро ​​базы данных из PHP и получении результатов. С этой техникой это происходит только один раз, а не один раз для каждого токена, поэтому производительность увеличится, я просто не знаю, будет ли этого достаточно.

 warren05 нояб. 2009 г., 07:50
Просто не забудьте использовать UNION ALL, а не просто UNION, иначе я не думаю, что вы получите несколько строк с тем же идентификатором, который вы хотите. - Rmbarnes 6 сентября 2008 года в 20:23
 warren05 нояб. 2009 г., 07:49
@rmbarnes - это должно быть там, где те UNION ops, которые я видел в основах БД много лет назад, внезапно обретают смысл; Я определенно оцениваю производительность, чтобы увидеть, как она сравнивается по общей скорости.

вы получите гораздо лучшую производительность, если будете использовать структуру данных, предназначенную для поисковых задач, а не базу данных. Например, вы можете попробовать посмотреть на созданиеперевернутый индекс, Однако, вместо того, чтобы писать самому, вы можете захотетьLucene которая делает большую часть работы для вас.

вы также можете включить в свой запрос следующие части:

SELECT COUNT(*) AS C
...
GROUP BY ID
ORDER BY c DESC

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

Ваш ответ на вопрос