实战系列之HNSW图快照更新性能测试

来源:这里教程网 时间:2026-03-03 22:54:52 作者:

DML压力测试

-- 创建测试表
CREATE TABLE hnsw_dml_test (
    product_id NUMBER PRIMARY KEY,
    product_name VARCHAR2(200),
    description VARCHAR2(4000),
    features VECTOR(768),
    last_updated DATE
);
-- 创建HNSW索引
CREATE VECTOR INDEX idx_hnsw_dml 
ON hnsw_dml_test(features)
ORGANIZATION INMEMORY NEIGHBOR GRAPH
DISTANCE COSINE;
-- 初始数据:100万条记录
INSERT INTO hnsw_dml_test
SELECT 
    LEVEL,
    'Product_' || LEVEL,
    DBMS_RANDOM.STRING('X', 200),
    VECTOR(768, RANDOM),
    SYSDATE
FROM dual CONNECT BY LEVEL <= 1000000;
COMMIT;

DML性能测试脚本

-- 并发DML测试
DECLARE
    TYPE id_array IS TABLE OF NUMBER;
    v_ids id_array;
    v_start_time NUMBER;
    v_end_time NUMBER;
    v_dml_count NUMBER := 0;
BEGIN
    v_start_time := DBMS_UTILITY.get_time;
    
    -- 模拟批量更新(50个并发会话)
    FOR i IN 1..50 LOOP
        DBMS_JOB.SUBMIT(
            job => i,
            what => 'BEGIN
                FOR j IN 1..1000 LOOP
                    UPDATE hnsw_dml_test 
                    SET features = VECTOR(768, RANDOM),
                        last_updated = SYSDATE
                    WHERE product_id = MOD(DBMS_RANDOM.VALUE(1,1000000), 100000) + 1;
                    IF MOD(j, 100) = 0 THEN COMMIT; END IF;
                END LOOP;
            END;'
        );
    END LOOP;
    
    -- 等待所有作业完成
    DBMS_LOCK.SLEEP(300); -- 5分钟
    
    v_end_time := DBMS_UTILITY.get_time;
    v_dml_count := 50000; -- 50会话 × 1000次/会话
    
    DBMS_OUTPUT.PUT_LINE('DML操作总数: ' || v_dml_count);
    DBMS_OUTPUT.PUT_LINE('总耗时: ' || (v_end_time - v_start_time)/100 || ' 秒');
    DBMS_OUTPUT.PUT_LINE('平均TPS: ' || 
        ROUND(v_dml_count / ((v_end_time - v_start_time)/100), 2));
END;
/

查询一致性验证

-- 在DML过程中验证查询一致性
SELECT COUNT(*) as inconsistent_records
FROM (
    -- 使用HNSW索引查询
    SELECT product_id 
    FROM hnsw_dml_test
    WHERE VECTOR_DISTANCE(features, 
          VECTOR(768, RANDOM), COSINE) < 0.1
    MINUS
    -- 使用传统索引验证
    SELECT product_id 
    FROM hnsw_dml_test t
    WHERE EXISTS (
        SELECT 1 FROM (
            SELECT product_id,
                   VECTOR_DISTANCE(features, 
                       VECTOR(768, RANDOM), COSINE) as dist
            FROM hnsw_dml_test
            ORDER BY dist
            FETCH FIRST 100 ROWS ONLY
        ) v
        WHERE v.product_id = t.product_id
    )
);
-- 结果应为0,表示无数据不一致

相关推荐

热文推荐