You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python PeeWee操作SQLite偶现插入延迟过高问题排查求助

问题描述

我正在开发一款程序,用于记录OpenCV读取的视频帧对应的GPS信息,采用PeeWee作为ORM框架操作SQLite数据库。正常情况下,数据库插入操作耗时<8ms,但偶尔会超过100ms,无法定位问题原因,寻求排查帮助。程序部署在Nvidia AGX Orin设备上,当执行到第10938次插入操作时,延迟达到了274ms。

程序代码
import json
import cv2
from datetime import datetime,timedelta
import time
import sqlite3
import pynmea2
import uuid
from peewee import *
from loguru import logger
import os


db_another = SqliteDatabase('robu_another3.db',pragmas={"journal_mode": "wal","cache_size":-1024*64,"page_size":32768,"synchronous":"normal","temp_store":"memory"}, timeout=40)

class LandscapeFrameTest(Model):
    timestamp = DateTimeField(verbose_name='时间戳', null=False)
    class Meta:
        table_name = 'frame_records_test'
        database = db_another
        order_by = ('timestamp',)

happen = 0
happen_10 = 0
happen_20 = 0
happen_100 = 0
all_time = 0

cap = cv2.VideoCapture("/dev/video2", cv2.CAP_V4L)
image_width = 1920
image_height = 1080
cap.set(cv2.CAP_PROP_FRAME_WIDTH, image_width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, image_height)
cap.set(cv2.CAP_PROP_FPS, 10)           #帧数
print('Opened: ',cap.isOpened())

db_another.drop_tables([LandscapeFrameTest])
db_another.create_tables([LandscapeFrameTest])

while True:
    ret, frame_read = cap.read()
    print(frame_read.shape)
    time_now = datetime.now()
    timestr_now_str = time_now.strftime('%Y-%m-%d %H:%M:%S.%f')
    print(timestr_now_str)
    frame_object = {"photo_time":timestr_now_str}
    start_p = time.time()
    f = LandscapeFrameTest(timestamp = frame_object['photo_time'])
    f.save(force_insert=True)
    end_p = time.time()
    framedb_cost = (end_p-start_p)*1000
    all_time = all_time+1
    logger.debug(db_another.get_primary_keys('frame_records_test'))
    if framedb_cost > 100:
        happen_100 = happen_100 +1
    elif framedb_cost > 20:
        happen_20 = happen_20 +1
    elif framedb_cost > 10:
        happen_10 = happen_10 +1
    logger.debug('Cost {} For {} ,Happen 100 {},Happen 20 {},Happen 10 {},After {}.'.format(framedb_cost,frame_object['photo_time'],happen_100,happen_20,happen_10,all_time))
    if framedb_cost > 100:
        break
    frame_nums = LandscapeFrameTest.select().count()
    logger.debug("Handle Frame Database  Frame All Count  {}".format(frame_nums))
运行日志片段
2023-02-19 07:47:07.216 | DEBUG    | main::63 - Handle Frame Database  Frame All Count  10936
(1080, 1920, 3)
2023-02-19 07:47:07.311356
2023-02-19 07:47:07.312 | DEBUG    | main::52 - ['id']
2023-02-19 07:47:07.312 | DEBUG    | main::59 - Cost 0.9157657623291016 For 2023-02-19 07:47:07.311356 ,Happen 100 0,Happen 20 3,Happen 10 0,After 10937.
2023-02-19 07:47:07.313 | DEBUG    | main::63 - Handle Frame Database  Frame All Count  10937
(1080, 1920, 3)
2023-02-19 07:47:07.411241
2023-02-19 07:47:07.685 | DEBUG    | main::52 - ['id']
2023-02-19 07:47:07.686 | DEBUG    | main::59 - Cost 274.2321491241455 For 2023-02-19 07:47:07.411241 ,Happen 100 1,Happen 20 3,Happen 10 0,After 10938.
排查方向与验证建议

可能的原因

  • SQLite WAL checkpoint 触发:WAL模式下,当WAL文件大小达到主数据库的70%时,SQLite会自动执行checkpoint操作,将WAL中的数据合并到主库,这个过程会短暂阻塞写入。
  • 磁盘I/O波动:AGX Orin的存储设备(如eMMC)可能被后台进程占用带宽,导致写入延迟突增。
  • ORM额外开销:PeeWee的对象创建、字段校验等逻辑,加上Python的垃圾回收,可能偶尔导致延迟升高。
  • 数据库锁竞争:若有其他进程/线程访问该数据库文件,会引发锁等待,拖慢插入速度。
  • 系统资源占用:高延迟发生时,AGX Orin的CPU、内存可能被其他进程抢占。

验证与优化步骤

  1. 移除额外数据库查询:注释掉每次插入后的db_another.get_primary_keys和LandscapeFrameTest.select().count(),这两个操作会额外消耗数据库资源,可能放大延迟。
  2. 对比原生SQL插入性能:替换PeeWee的插入代码为原生SQL,判断是否是ORM导致的问题:
    start_p = time.time()
    db_another.execute_sql("INSERT INTO frame_records_test (timestamp) VALUES (?)", (frame_object['photo_time'],))
    end_p = time.time()
    
  3. 监控WAL文件与checkpoint:定期打印robu_another3.db-wal文件大小,确认高延迟是否发生在checkpoint触发节点;也可手动设置wal_autocheckpoint调整触发阈值,例如:
    db_another.execute_sql("PRAGMA wal_autocheckpoint=10000")
    
  4. 系统资源监控:在延迟发生时,用iostat查看磁盘I/O负载,top查看CPU、内存占用情况,确认是否有后台进程干扰。
  5. 开启SQLite性能追踪:添加pragmas={"trace": "profile"}到数据库连接,查看高延迟时的SQL执行细节。

内容的提问来源于stack exchange,提问作者Shawn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:59:21