如何优化SQLite平台插入查询?适配所有media_capture_form行
解决方案
1. 先给platforms表添加联合唯一约束(关键前提)
为了从根源避免重复插入,同时保证每个表单(formPky)对应平台名称唯一,先给platforms表创建联合唯一索引:
CREATE UNIQUE INDEX idx_platforms_form_name ON platforms(formPky, name);
这样后续插入时可以用INSERT OR IGNORE,无需额外的WHERE子查询判断重复,更高效简洁。
2. 修改插入查询,适配所有media_capture_form行
原查询的SELECT 1,?,...固定了formPky=1,仅处理第一行记录。现在改为从media_capture_form表中取出所有formPky,和新平台名称组合生成待插入数据,同时利用INSERT OR IGNORE跳过已存在的记录:
def addPlatform(self, platformName): # 为media_capture_form的每一行都插入对应新平台的记录,自动跳过已存在的(formPky,name)组合 sql = """ INSERT OR IGNORE INTO platforms (formPky, name, chk, url, date, opt_a, opt_b, opt_c) SELECT m.formPky, ?, '', '', '', '', '', '' FROM media_capture_form m """ self.runCommand(sql, (platformName,))
3. 可选:用EXISTS替代IN做重复判断(无法修改表结构时)
如果暂时无法添加唯一索引,也可以用EXISTS精准判断当前formPky+name组合是否已存在。因为数据量小,性能差异可以忽略,但逻辑更严谨:
def addPlatform(self, platformName): sql = """ INSERT INTO platforms (formPky, name, chk, url, date, opt_a, opt_b, opt_c) SELECT m.formPky, ?, '', '', '', '', '', '' FROM media_capture_form m WHERE NOT EXISTS ( SELECT 1 FROM platforms p WHERE p.formPky = m.formPky AND p.name = ? ) """ self.runCommand(sql, (platformName, platformName))
方案说明
- 第一种方案(加唯一索引+INSERT OR IGNORE)是SQLite中处理重复插入最推荐的方式,执行效率高,代码简洁,利用数据库约束保证数据唯一性。
- 第二种方案适合无法修改表结构的场景,通过
EXISTS子查询避免插入已存在的关联记录。 - 结合你提到的平台列表和
media_capture_form行数都不多的情况,两种方案的性能差异可以忽略,优先选择第一种。
内容的提问来源于stack exchange,提问作者Thomas Freedman
相关产品推荐
相关产品推荐

