문제

웹앱 개발 문제에 대한 하나의 솔루션을 개발했지만 현재 보고 있는 일부 성능 문제를 해결할 수 있는 다른 아이디어를 찾으려고 노력하고 있습니다.

문제 설명:

  • 사용자가 여러 키워드/토큰을 입력합니다.
  • 애플리케이션은 토큰과 일치하는 항목을 검색합니다.
  • 각 토큰에 대해 하나의 결과가 필요합니다.
    • 즉, 항목에 3개의 토큰이 있는 경우 항목 ID가 3번 필요합니다.
  • 결과의 순위를 매기다
    • 토큰 매치에 X 포인트 할당
    • 포인트를 기준으로 항목 ID를 정렬합니다.
    • 포인트 값이 동일한 경우 날짜를 사용하여 결과 정렬

내가 할 수 있기를 원하지만 파악하지 못한 것은 in()의 결과와 유사한 것을 반환하지만 확인된 각 항목 ID에 대해 일치하는 각 토큰에 대해 중복 항목 ID를 반환하는 1개의 쿼리를 보내는 것입니다.

내가 하고 있는 것, 즉 토큰당 하나의 쿼리를 실행하는 여러 개의 개별 쿼리를 사용하는 것보다 더 나은 방법이 있습니까?그렇다면 이를 구현하는 가장 쉬운 방법은 무엇입니까?

편집하다
이미 항목을 토큰화했습니다. 예를 들어 "see spot run"의 항목 ID는 1이고 세 개의 토큰 'see', 'spot', 'run'이 있으며 이는 별도의 토큰 테이블에 있습니다. 관련 항목 ID가 있으므로 테이블은 다음과 같습니다.

'see', 1 
'spot', 1 
'run', 1 
'run', 2 
'spot', 3 
도움이 되었습니까?

해결책

MySQL에서 'UNION ALL'을 사용하여 하나의 쿼리로 이를 달성할 수 있습니다.

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

이것은 매우 사소한 예이지만 각 결과에 대한 일치 빈도를 얻을 수 있으며 이는 시작하기 위한 의사 순위일 수 있습니다.

데이터베이스가 아닌 검색 작업용으로 설계된 데이터 구조를 사용했다면 아마도 훨씬 더 나은 성능을 얻을 수 있을 것입니다.예를 들어, 반전된 인덱스.그러나 직접 작성하기보다는 다음과 같은 내용을 살펴보는 것이 좋습니다. 루씬 이는 대부분의 작업을 수행합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top