RUM 색인 만들기 및 관리

이 문서에서는 RUM 확장 프로그램을 만들고 PostgreSQL용 AlloyDB에서 전체 텍스트 검색을 최적화하기 위해 색인을 만드는 방법을 보여줍니다. 순위 지정, 구문 검색, 타임스탬프별 정렬을 비롯한 일반적인 사용 사례의 예를 제공합니다.

시작하기 전에

RUM 확장 프로그램을 만들려면 alloydb_superuser 역할이 있어야 합니다. 역할 부여에 대한 자세한 내용은 클러스터에 IAM 사용자 또는 서비스 계정 추가를 참조하세요.

RUM 확장 프로그램 만들기

데이터베이스당 한 번 RUM 확장 프로그램을 만들어야 합니다.

  1. psql 또는 다른 클라이언트를 사용하여 AlloyDB 데이터베이스에 연결합니다. 자세한 내용은 클러스터 인스턴스에 연결을 참조하세요.
  2. 다음 SQL 명령어를 실행하여 확장 프로그램을 만듭니다.

    CREATE EXTENSION IF NOT EXISTS rum;
    

RUM 색인 만들기

전체 텍스트 검색 쿼리를 최적화하려면 데이터에 RUM 색인을 만듭니다. RUM은 다양한 사용 사례를 위한 여러 연산자 클래스를 제공합니다.

RUM 연산자 클래스 유형

다음 표에는 다양한 RUM 연산자 클래스와 기본 사용 사례가 요약되어 있습니다.

연산자 클래스 주요 사용 사례 제한사항
rum_tsvector_ops 순위 지정 및 구문 검색이 포함된 표준 전체 텍스트 검색 해당 사항 없음
rum_tsvector_hash_ops 전체 텍스트 검색을 위한 더 작은 색인과 빠른 업데이트 프리픽스 검색을 지원하지 않습니다.
rum_tsvector_addon_ops 다른 열을 기준으로 정렬된 전체 텍스트 검색 해당 사항 없음
rum_anyarray_ops 배열 열 내에서 검색 해당 사항 없음
rum_<TYPE>_ops 거리 기반 쿼리를 위한 스칼라 유형 색인 생성 해당 사항 없음
rum_tsvector_hash_addon_ops 다른 열을 기준으로 정렬된 해시 기반 전체 텍스트 검색 프리픽스 일치를 지원하지 않습니다.
rum_tsquery_ops 역방향 검색을 위해 저장된 tsquery 값 색인 생성 해당 사항 없음
rum_anyarray_addon_ops 다른 열을 기준으로 정렬된 배열 검색 해당 사항 없음

빠른 순위 지정 및 구문 검색 기능이 필요한 표준 텍스트 검색에는 rum_tsvector_ops 연산자 클래스를 사용합니다. 이 연산자 클래스는 색인에 각 형태소의 위치를 저장합니다. 다음 예에서는 content 열이 있는 documents라는 테이블을 만듭니다.

  1. documents라는 테이블을 만듭니다.

    CREATE TABLE documents (
      id SERIAL PRIMARY KEY,
      title TEXT NOT NULL,
      content TEXT NOT NULL,
      published_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
    );
    
  2. 샘플 데이터로 documents 테이블을 채웁니다.

    INSERT INTO documents (title, content) VALUES
      ('Title', 'This search engine is working as intended');
    
  3. 생성된 tsvector 열을 테이블에 추가합니다. 이 열은 처리된 텍스트를 자동으로 저장하고 쿼리 성능을 개선합니다.

    ALTER TABLE documents
    ADD COLUMN search_vector tsvector
    GENERATED ALWAYS AS (to_tsvector('english', content)) STORED;
    
  4. search_vector 열에 RUM 색인을 만듭니다.

    CREATE INDEX idx_docs_rum
    ON documents
    USING rum (search_vector rum_tsvector_ops);
    
  5. 색인을 사용하여 테이블을 쿼리합니다. <=> 연산자는 색인에서 직접 문서와 쿼리 간의 관련성 점수 또는 거리를 계산하여 빠른 정렬을 지원합니다.

    SELECT title, content
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'search <-> engine')
    ORDER BY search_vector <=> to_tsquery('english', 'search <-> engine');
    
  6. 추가 데이터로 documents 테이블을 채웁니다.

    INSERT INTO documents (title, content) VALUES ('Title1', 'English is my primary language.');
    INSERT INTO documents (title, content) VALUES ('Title2', 'Google has a great engineering culture');
    
  7. 프리픽스 검색 쿼리를 실행합니다. 이렇게 하면 engineer 또는 english와 같이 eng로 시작하는 단어가 포함된 문서가 검색됩니다.

    SELECT title, content
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'eng:*');
    

rum_tsvector_hash_ops 연산자 클래스를 사용하여 색인 크기를 줄이고 업데이트 속도를 개선합니다. 이 클래스는 전체 형태소 대신 각 형태소의 해시를 저장합니다. 이 접근 방식은 더 작은 색인을 생성하지만 프리픽스 검색을 지원하지 않습니다. 다음 예에서는 search_vector 열이 있는 documents라는 테이블이 있다고 가정합니다.

  1. 해시 연산자 클래스를 사용하여 RUM 색인을 만듭니다.

    CREATE INDEX idx_docs_rum_hash
    ON documents
    USING rum (search_vector rum_tsvector_hash_ops);
    
  2. 추가 데이터로 documents 테이블을 채웁니다.

    INSERT INTO documents (title, content) VALUES ('Title3', 'That person was driving incredibly fast, however the routing was not very efficient');
    
  3. 표준 일치 쿼리를 실행합니다.

    SELECT * FROM documents WHERE search_vector @@ to_tsquery('english', 'fast & efficient');
    
    

타임스탬프별로 정렬된 검색 색인

rum_tsvector_addon_ops 연산자 클래스를 사용하여 텍스트로 필터링하고 타임스탬프와 같은 다른 필드를 기준으로 정렬하는 쿼리를 최적화합니다. 이 패턴은 추가 필드의 값을 색인에 직접 저장하므로 검색 후 느린 정렬 작업을 방지합니다. 다음 예에서는 search_vector 열과 published_at 열이 있는 documents라는 테이블이 있다고 가정합니다.

  1. published_at 타임스탬프가 포함된 색인을 만듭니다.

    CREATE INDEX idx_docs_rum_timestamp
    ON documents
    USING rum (search_vector rum_tsvector_addon_ops, published_at)
    WITH (attach = 'published_at', to = 'search_vector');
    
  2. engine이라는 단어가 포함된 문서를 찾고 게시일별로 정렬하는 쿼리를 실행합니다. 색인은 검색과 정렬을 모두 효율적으로 처리합니다.

    SELECT title, published_at
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'engine')
    ORDER BY published_at DESC;
    

rum_anyarray_ops 연산자 클래스를 사용하여 태그 목록과 같은 배열 열의 색인을 생성합니다. 이렇게 하면 겹치거나 (&&) 포함하거나 (@>) 다른 배열에 포함된 (<@) 배열을 효율적으로 쿼리할 수 있습니다. 다음 예에서는 documents 테이블에 tags 열을 추가합니다.

  1. tags 열을 추가하고 데이터로 채웁니다.

    ALTER TABLE documents 
    ADD COLUMN tags TEXT[];
    
    INSERT INTO documents (title, content, tags) VALUES ( 'Title4', 'Sample Text', ARRAY['ai', 'ml'] );
    
  2. tags라는 TEXT[] 열에 RUM 색인을 만듭니다.

    CREATE INDEX idx_tags_rum
    ON documents
    USING rum (tags rum_anyarray_ops);
    
  3. 태그에 ai 또는 ml이 있는 문서를 찾는 쿼리를 실행합니다.

    SELECT * FROM documents WHERE tags && '{"ai", "ml"}';
    

스칼라 유형 색인

rum_<TYPE>_ops 연산자 클래스를 사용하여 정수, 타임스탬프 또는 부동 소수점 수와 같은 연속 값이 포함된 열의 색인을 생성합니다. 이러한 연산자 클래스를 사용하면 <=> 연산자를 사용하여 값 간의 거리 를 효율적으로 계산할 수 있습니다. 다음 예에서는 documents라는 테이블이 있다고 가정합니다.

  1. documents 테이블에 rating과 같은 일반 정수 열을 추가합니다.

    ALTER TABLE documents
    ADD COLUMN rating INT;
    
    UPDATE documents 
    SET rating = floor(random() * 5 + 1);
    
  2. rating 열에 RUM 색인을 만듭니다.

    CREATE INDEX idx_rating_rum
    ON documents
    USING rum (rating rum_int4_ops);
    
  3. 값 5에 가장 가까운 rating이 있는 문서를 찾는 쿼리를 실행합니다.

    SELECT title, rating
    FROM documents
    ORDER BY rating <=> 5;
    

타임스탬프별로 정렬된 최적화된 해시 검색 색인

rum_tsvector_hash_addon_ops 연산자 클래스를 사용하여 해시 색인의 이점과 애드온 색인의 정렬 기능을 결합합니다. 이 클래스는 추가 열의 값과 함께 각 형태소의 해시를 저장합니다. 이 구성은 추가 열을 기준으로 효율적인 정렬을 지원하지만 프리픽스 일치를 지원하지 않습니다. 다음 예에서는 search_vector 열과 published_at 타임스탬프 열이 있는 documents라는 테이블이 있다고 가정합니다.

  1. 해시 연산자 클래스를 사용하고 published_at 타임스탬프를 포함하는 RUM 색인을 만듭니다.

    CREATE INDEX idx_docs_rum_hash_timestamp
    ON documents
    USING rum (search_vector rum_tsvector_hash_addon_ops, published_at)
    WITH (attach = 'published_at', to = 'search_vector');
    
  2. engine이 포함된 문서를 찾고 게시일별로 정렬하는 쿼리를 실행합니다.

    SELECT title, published_at
    FROM documents
    WHERE search_vector @@ to_tsquery('english', 'engine')
    ORDER BY published_at DESC;
    

저장된 쿼리 색인

rum_tsquery_ops 연산자 클래스를 사용하여 tsquery 값의 색인을 생성합니다. 이렇게 하면 '역방향 검색'을 수행하여 지정된 입력 문서와 일치하는 저장된 쿼리를 식별할 수 있습니다. 다음 예에서는 queries라는 테이블을 만듭니다.

  1. 쿼리를 저장할 테이블을 만듭니다.

    CREATE TABLE queries (
    query_text tsquery
    );
    INSERT INTO queries (query_text) VALUES (plainto_tsquery('AlloyDB is fast!'));
    
  2. query_text 열에 RUM 색인을 만듭니다.

    CREATE INDEX idx_queries_rum
    ON queries
    USING rum (query_text rum_tsquery_ops);
    
  3. 문서와 일치하는 저장된 쿼리를 찾는 쿼리를 실행합니다.

    SELECT *
    FROM queries
    WHERE to_tsvector('english', 'AlloyDB is fast') @@ query_text;
    

타임스탬프별로 정렬된 배열 검색 색인

rum_anyarray_addon_ops 연산자 클래스를 사용하여 정렬을 위한 추가 열과 함께 배열 열의 색인을 생성합니다. 다음 예에서는 tags 열과 published_at 타임스탬프 열이 있는 documents라는 테이블이 있다고 가정합니다.

  1. published_at 타임스탬프가 포함된 tags 열에 RUM 색인을 만듭니다.

    CREATE INDEX idx_tags_rum_timestamp
    ON documents
    USING rum (tags rum_anyarray_addon_ops, published_at)
    WITH (attach = 'published_at', to = 'tags');
    
  2. 게시일별로 정렬된 ai 태그가 있는 문서를 찾는 쿼리를 실행합니다.

    SELECT title, published_at
    FROM documents
    WHERE tags @> '{"ai"}'
    ORDER BY published_at DESC;
    

다음 단계

달리 명시되지 않는 한 이 페이지의 콘텐츠에는 Creative Commons Attribution 4.0 라이선스에 따라 라이선스가 부여되며, 코드 샘플에는 Apache 2.0 라이선스에 따라 라이선스가 부여됩니다. 자세한 내용은 Google Developers 사이트 정책을 참조하세요. 자바는 Oracle 및/또는 Oracle 계열사의 등록 상표입니다.

최종 업데이트: 2026-03-25(UTC)