在 AlloyDB Omni 中执行向量搜索

选择文档版本:

本教程介绍了如何使用 Google Cloud 控制台在 AlloyDB Omni 中设置并执行向量搜索。其中包含一些示例,用于展示向量搜索功能,这些示例仅用于演示目的。

如需了解如何使用过滤的向量搜索来优化相似度搜索,请参阅 AlloyDB Omni 中的过滤向量搜索

如需了解如何使用 Vertex AI 嵌入执行向量搜索,请参阅开始使用 AlloyDB Omni AI 处理向量嵌入

目标

  • 创建 AlloyDB Omni 集群和主实例。
  • 连接到您的数据库并安装所需的扩展程序。
  • 创建 productproduct inventory 表。
  • 将数据插入 productproduct inventory 表,并执行基本向量搜索。
  • 在商品表上创建 ScaNN 索引。
  • 执行基本向量搜索。
  • 执行包含过滤条件和联接的复杂向量搜索。

费用

在本文档中,您将使用 Google Cloud的以下收费组件:

如需根据您的预计使用量来估算费用,请使用价格计算器

新 Google Cloud 用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅“清理”。

前提条件

在执行向量搜索之前,请完成以下前提条件:

插入商品和商品目录数据,并执行基本向量搜索

  1. 运行以下语句,以创建执行以下操作的 product 表:

    • 存储基本商品信息。
    • 包含 embedding 向量列,用于计算和存储每个商品的商品说明的嵌入向量。
      CREATE TABLE product (
        id INT PRIMARY KEY,
        name VARCHAR(255) NOT NULL,
        description TEXT,
        category VARCHAR(255),
        color VARCHAR(255),
        embedding vector(768) GENERATED ALWAYS AS (embedding('text-embedding-005', description)) STORED
      );
    

    如有需要,您可以查看日志并排查错误。

  2. 运行以下查询,以创建一个 product_inventory 表,用于存储有关可用商品目录和相应价格的信息。在本教程中,我们将使用 product_inventoryproduct 表运行复杂的向量搜索查询。

    CREATE TABLE product_inventory (
      id INT PRIMARY KEY,
      product_id INT REFERENCES product(id),
      inventory INT,
      price DECIMAL(10,2)
    );
    
  3. 运行以下查询,以将商品数据插入 product 表中:

    INSERT INTO product (id, name, description,category, color) VALUES
    (1, 'Stuffed Elephant', 'Soft plush elephant with floppy ears.', 'Plush Toys', 'Gray'),
    (2, 'Remote Control Airplane', 'Easy-to-fly remote control airplane.', 'Vehicles', 'Red'),
    (3, 'Wooden Train Set', 'Classic wooden train set with tracks and trains.', 'Vehicles', 'Multicolor'),
    (4, 'Kids Tool Set', 'Toy tool set with realistic tools.', 'Pretend Play', 'Multicolor'),
    (5, 'Play Food Set', 'Set of realistic play food items.', 'Pretend Play', 'Multicolor'),
    (6, 'Magnetic Tiles', 'Set of colorful magnetic tiles for building.', 'Construction Toys', 'Multicolor'),
    (7, 'Kids Microscope', 'Microscope for kids with different magnification levels.', 'Educational Toys', 'White'),
    (8, 'Telescope for Kids', 'Telescope designed for kids to explore the night sky.', 'Educational Toys', 'Blue'),
    (9, 'Coding Robot', 'Robot that teaches kids basic coding concepts.', 'Educational Toys', 'White'),
    (10, 'Kids Camera', 'Durable camera for kids to take pictures and videos.', 'Electronics', 'Pink'),
    (11, 'Walkie Talkies', 'Set of walkie talkies for kids to communicate.', 'Electronics', 'Blue'),
    (12, 'Karaoke Machine', 'Karaoke machine with built-in microphone and speaker.', 'Electronics', 'Black'),
    (13, 'Kids Drum Set', 'Drum set designed for kids with adjustable height.', 'Musical Instruments', 'Blue'),
    (14, 'Kids Guitar', 'Acoustic guitar for kids with nylon strings.', 'Musical Instruments', 'Brown'),
    (15, 'Kids Keyboard', 'Electronic keyboard with different instrument sounds.', 'Musical Instruments', 'Black'),
    (16, 'Art Easel', 'Double-sided art easel with chalkboard and whiteboard.', 'Arts & Crafts', 'White'),
    (17, 'Finger Paints', 'Set of non-toxic finger paints for kids.', 'Arts & Crafts', 'Multicolor'),
    (18, 'Modeling Clay', 'Set of colorful modeling clay.', 'Arts & Crafts', 'Multicolor'),
    (19, 'Watercolor Paint Set', 'Watercolor paint set with brushes and palette.', 'Arts & Crafts', 'Multicolor'),
    (20, 'Beading Kit', 'Kit for making bracelets and necklaces with beads.', 'Arts & Crafts', 'Multicolor'),
    (21, '3D Puzzle', '3D puzzle of a famous landmark.', 'Puzzles', 'Multicolor'),
    (22, 'Race Car Track Set', 'Race car track set with cars and accessories.', 'Vehicles', 'Multicolor'),
    (23, 'RC Monster Truck', 'Remote control monster truck with oversized tires.', 'Vehicles', 'Green'),
    (24, 'Train Track Expansion Set', 'Expansion set for wooden train tracks.', 'Vehicles', 'Multicolor');
    
  4. 可选:运行以下查询,以验证数据是否已插入 product 表中:

    SELECT * FROM product;
    
  5. 运行以下查询,以将商品目录数据插入 product_inventory 表中:

    INSERT INTO product_inventory (id, product_id, inventory, price) VALUES
    (1, 1, 9, 13.09),
    (2, 2, 40, 79.82),
    (3, 3, 34, 52.49),
    (4, 4, 9, 12.03),
    (5, 5, 36, 71.29),
    (6, 6, 10, 51.49),
    (7, 7, 7, 37.35),
    (8, 8, 6, 10.87),
    (9, 9, 7, 42.47),
    (10, 10, 3, 24.35),
    (11, 11, 4, 10.20),
    (12, 12, 47, 74.57),
    (13, 13, 5, 28.54),
    (14, 14, 11, 25.58),
    (15, 15, 21, 69.84),
    (16, 16, 6, 47.73),
    (17, 17, 26, 81.00),
    (18, 18, 11, 91.60),
    (19, 19, 8, 78.53),
    (20, 20, 43, 84.33),
    (21, 21, 46, 90.01),
    (22, 22, 6, 49.82),
    (23, 23, 37, 50.20),
    (24, 24, 27, 99.27);
    
  6. 运行以下向量搜索查询,尝试查找与字词 music 类似的商品。这意味着,即使商品说明中未明确提及 music 一词,结果也会显示与查询相关的商品:

    SELECT * FROM product
    ORDER BY embedding <=> embedding('text-embedding-005', 'music')::vector
    LIMIT 3;
    

    查询结果如下所示: 基本搜索查询结果

    在未创建索引的情况下执行基本向量搜索会使用精确最近邻搜索 (KNN),从而提供高效的召回率。大规模使用 KNN 可能会影响性能。为了获得更好的查询性能,我们建议您使用 ScaNN 索引进行近似最近邻 (ANN) 搜索,该索引可在低延迟的情况下提供高召回率。

    在未创建索引的情况下,AlloyDB Omni 默认使用精确最近邻搜索 (KNN)。

    如需详细了解如何大规模使用 ScaNN,请参阅开始使用 AlloyDB AI 处理向量嵌入

在商品表上创建手动调优的 ScaNN 索引

运行以下查询,以在 product 表上创建 product_index ScaNN 索引:

CREATE INDEX product_index ON product
USING scann (embedding cosine)
WITH (mode='MANUAL', num_leaves=4);

如需详细了解如何创建 ScaNN 索引,请参阅创建 ScaNN 索引

运行以下向量搜索查询,尝试查找与自然语言查询 music 类似的商品。即使商品说明中未包含 music 字词,结果也会显示与查询相关的商品:

SET LOCAL scann.num_leaves_to_search = 2;

SELECT * FROM product
ORDER BY embedding <=> embedding('text-embedding-005', 'music')::vector
  LIMIT 3;

查询结果如下: 向量搜索查询结果

scann.num_leaves_to_search 查询参数用于控制在相似度搜索期间搜索的叶节点数量。num_leavesscann.num_leaves_to_search 参数值有助于在性能和召回率之间取得平衡。

即使使用 ScaNN 索引,您也可以高效运行过滤的向量搜索查询。运行以下复杂的向量搜索查询,该查询会返回满足查询条件的相关结果,即使具有过滤条件也是如此:

SET LOCAL scann.num_leaves_to_search = 2;

SELECT * FROM product p
JOIN product_inventory pi ON p.id = pi.product_id
WHERE pi.price < 80.00
ORDER BY embedding <=> embedding('text-embedding-005', 'music')::vector
LIMIT 3;

在数据库中,当列式引擎与高选择性谓词过滤(例如使用 LIKE)相结合时,可以提高向量相似度搜索(尤其是 K 最近邻 [KNN] 搜索)的性能。在本部分中,您将使用 vector 扩展程序和 AlloyDB Omni google_columnar_engine 扩展程序。如需详细了解列式引擎的运作方式,请参阅列式引擎概览

性能提升得益于列式引擎在扫描大型数据集和应用过滤条件(例如 LIKE 谓词)方面的内置效率,以及它使用向量支持预过滤行的能力。此功能可减少后续 KNN 向量距离计算所需的数据子集数量,并有助于优化涉及标准过滤和向量搜索的复杂分析查询。

列式存储区提供了两种管理其内容的方式:

如需比较启用列式引擎前后按 LIKE 谓词过滤的 KNN 向量搜索的执行时间,请按照以下步骤操作:

  1. 启用 vector 扩展程序以支持向量数据类型和运算。运行以下语句以创建一个示例表 (items),其中包含 ID、文本说明和 512 维向量嵌入列。

    CREATE EXTENSION IF NOT EXISTS vector;
    
    CREATE TABLE items (
        id SERIAL PRIMARY KEY,
        description TEXT,
        embedding VECTOR(512)
    );
  2. 通过运行以下语句将 100 万行数据插入示例 items 表中,来填充数据。

    -- Simplified example of inserting matching (~0.1%) and non-matching data
    INSERT INTO items (description, embedding)
    SELECT
        CASE WHEN g % 1000 = 0 THEN 'product_' || md5(random()::text) || '_common' -- ~0.1% match
        ELSE 'generic_item_' || g || '_' || md5(random()::text)    -- ~99.9% don't match
        END,
        (SELECT array_agg(random()) FROM generate_series(1, 512))::vector
    FROM generate_series(1, 999999) g;
  3. 衡量不使用列式引擎时的向量相似度搜索基准性能。

    SELECT id, description, embedding <-> '[...]' AS distance
    FROM items
    WHERE description LIKE '%product_%_common%'
    ORDER BY embedding <-> '[...]'
    LIMIT 100;
  4. 启用列式引擎和向量支持。

    1. 启用 google_columnar_engine.enabledgoogle_columnar_engine.enable_vector_support 数据库标志。

      ALTER SYSTEM SET google_columnar_engine.enabled = 'on';
      ALTER SYSTEM SET google_columnar_engine.enable_vector_support = 'on';
    2. 重启 AlloyDB Omni

      systemctl restart alloydbomni18
  5. items 表添加到列式引擎:

    SELECT google_columnar_engine_add('items');
  6. 使用列式引擎衡量向量相似度搜索的性能。重新运行之前运行的查询,以衡量基准性能。

    SELECT id, description, embedding <-> '[...]' AS distance
    FROM items
    WHERE description LIKE '%product_%_common%'
    ORDER BY embedding <-> '[...]'
    LIMIT 100;
  7. 如需检查查询是否使用列式引擎运行,请运行以下命令:

    explain (analyze) SELECT id, description, embedding <-> '[...]' AS distance
    FROM items
    WHERE description LIKE '%product_%_common%'
    ORDER BY embedding <-> '[...]'
    LIMIT 100;

清理

如需卸载 AlloyDB Omni,请参阅管理和监控 AlloyDB Omni

后续步骤