果蔬识别系统性能优化之路(四)

目录

前情提要

果蔬识别系统性能优化之路(三)

剩下问题

同步数据库数据并初始化ivf依然要8,9秒

问题排查

通过断点加时间打印,发生其实初始化ivf的时间很快,慢的是数据在网络间的传输,并在python端的数据解析,无语


本地调本地,都要十秒,这不合理,改!

解决方案

因为这里必须要查一次全量数据,然后存入redis并将特征值传给python端进行初始化,所以最快的方案就是舍弃数据传输,直接在python端进行查询并初始化,即在python端查全量数据+设置redis+初始化ivf,虽然不想承认,但确实把python端做重在架构和设计层面可能都是最优解,改吧

  1. python端增加mysql查询
python 复制代码
import mysql.connector
from mysql.connector import pooling

# 配置数据库连接
db_config = {
    'host': 'localhost',  # 替换为你的 MySQL 主机地址
    'user': 'root',  # 替换为你的 MySQL 用户名
    'password': 'cmkkl407',  # 替换为你的 MySQL 密码
    'database': 'cnn'  # 替换为你的数据库名称
}
pool = pooling.MySQLConnectionPool(pool_name="mypool", pool_size=5, **db_config)


def get_feature_by_store_code(store_code):
    query = "SELECT id, features FROM feature WHERE storeCode REGEXP %s"
    results = query_data(query, params=(f"(^|,){store_code}(,|$)",))
    return results


def query_data(query, params):
    connection = pool.get_connection()
    cursor = connection.cursor(dictionary=True)
    cursor.execute(query, params)
    results = cursor.fetchall()
    cursor.close()
    connection.close()  # 连接会被返回到池中
    return results
  1. 修改sync方法
python 复制代码
  def sync(self, store_code):
        if store_code + '-featureDatabase' in self.ivfObj:
            del self.ivfObj[store_code + '-featureDatabase']
        data = get_feature_by_store_code(store_code)

        def parse_features(item):
            return orjson.loads(item['features'])

        with ThreadPoolExecutor() as executor:
            features_list = list(executor.map(parse_features, data))
        # 提取所有特征并转换为 NumPy 数组
        features = np.array(features_list, dtype=np.float32)
        self.ivfObj[store_code + '-featureDatabase'] = IVFPQ(features)
        ids = [item['id'] for item in data]
        return ids

由于python端查出来的json默认会给字符串格式,所以还需要转成json

一个优化小点:

并行处理:使用多线程或多进程并行处理数据。可以使用 concurrent.futures 库中的 ThreadPoolExecutor 或 ProcessPoolExecutor 来加快解析速度。

python 复制代码
   def parse_features(item):
            return orjson.loads(item['features'])

        with ThreadPoolExecutor() as executor:
            features_list = list(executor.map(parse_features, data))

同时利用查出了所有id将ids进行返回给nestjs端直接进行redis存储

  1. nestjs端修改
typescript 复制代码
 /**
   * 同步redis
   * @param storeCode
   */
  async syncRedis(storeCode: string) {
    const url = 'http://localhost:5000/sync'; // Python 服务的 URL
    const s = Date.now();
    const response = await firstValueFrom(this.httpService.post(url, { storeCode }));
    const { ids } = response.data;
    await this.redisService.set(`${storeCode}-featureDatabase`, JSON.stringify(ids));
    const e = Date.now();
    console.log(`同步redis耗时:${e - s}ms`);
  }
  1. 优化后速度减少了一倍

下一步

  1. 新建store_feature表,关联storeCode和featureId表,对数据库进行规范化,创建一个新的表来映射storeCode与feature的关系,从而可以使用简单的WHERE条件来充分利用索引
  2. 实现对特征向量ivf的增删改查
相关推荐
阿酷tony6 分钟前
Nano Banna 提示词:创意超逼真的3D商业风格产品图
人工智能·3d·gemini·图片生成
swipe9 分钟前
AI 应用里的 Memory,不是“保存聊天记录”,而是管理上下文预算
前端·llm·agent
披着羊皮不是狼16 分钟前
MSE、MAE、Binary/Categorical Cross-Entropy、HingeLoss五种损失函数的典型应用场景
人工智能·损失函数
guslegend17 分钟前
大模型RAG进阶多格式文档解析
人工智能·大模型
慧一居士24 分钟前
nuxt3 项目和nuxt4 项目区别和对比
前端·vue.js
独角鲸网络安全实验室31 分钟前
惊魂零点击!OpenClaw漏洞(ClawJacked)突袭,开发者AI Agent遭无声劫持
人工智能·网络安全·数据安全·漏洞·openclaw·clawjacked·cve-2026-25253
嘎嘎嘎嘎降34 分钟前
保姆级教程:25个降AI提示词大全,手把手教你去AI味
人工智能·去ai味提示词大全·降ai提示词·降ai指令·deepseek降ai
irizhao37 分钟前
《高质量数据集 质量评测规范》(TC609-5-2025-04)
人工智能·分类·数据挖掘
zero159737 分钟前
SpecCoding:规范驱动开发的工具与方法论全解析
人工智能·ai智能体
monsion38 分钟前
Code Agent 的上下文压缩:不是 zip,而是工作记忆管理
大数据·人工智能