Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中缩短sqlite3执行/获取时间 上下文_Python_Sqlite - Fatal编程技术网

在python中缩短sqlite3执行/获取时间 上下文

在python中缩短sqlite3执行/获取时间 上下文,python,sqlite,Python,Sqlite,我正在处理几个以专有格式存储电力系统解决方案结果的文件。数据的格式相当简单,但每个结果文件约为50MB。提供了一个用于查询文件格式的API,但我需要进行大量查询,而且API速度非常慢 我编写了一个程序,使用API将这些文件中的几个文件相互比较,并让它运行了几个小时,但没有结果。我的下一个想法是对文件进行一次遍历,将需要的数据存储到sqlite3数据库中,然后查询它。这让我在20分钟内得到了一个结果。好多了。重新构造数据以尽可能避免连接:12分钟。将.db文件存储在临时本地位置而不是网络上:8.5

我正在处理几个以专有格式存储电力系统解决方案结果的文件。数据的格式相当简单,但每个结果文件约为50MB。提供了一个用于查询文件格式的API,但我需要进行大量查询,而且API速度非常慢

我编写了一个程序,使用API将这些文件中的几个文件相互比较,并让它运行了几个小时,但没有结果。我的下一个想法是对文件进行一次遍历,将需要的数据存储到sqlite3数据库中,然后查询它。这让我在20分钟内得到了一个结果。好多了。重新构造数据以尽可能避免连接:12分钟。将.db文件存储在临时本地位置而不是网络上:8.5分钟

进一步改进 该程序在当前速度下或多或少是可以忍受的,但该程序在完成后每天将运行很多次。目前,62%的运行时间用于721次.execute/.fetchone调用

      160787763 function calls (160787745 primitive calls) in 503.061 seconds
Ordered by: internal time
List reduced from 1507 to 20 due to restriction <20>
ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   721  182.869    0.254  182.869    0.254 {method 'fetchone' of 'sqlite3.Cursor' objects}
   721  129.355    0.179  129.355    0.179 {method 'execute' of 'sqlite3.Cursor' objects}
 24822   45.734    0.002   47.600    0.002 {method 'executemany' of 'sqlite3.Connection' objects}
dict结构是:

dict = {(solution_id, num): [db1_val, db2_val, db3_val, db4_val]}
每个条目至少有一个db_val,其他条目则没有。上面循环的目的是填充每个可以填充的db_val点,以便比较值

问题 我已经读到sqlite3 SELECT语句只能使用.execute执行,因此我无法使用.executemany(这为我节省了大量的插入时间)。我还阅读了python文档,使用.execute直接从connection对象执行会更有效,但我不能这样做,因为我需要获取数据

是否有更好的方法来构造循环或查询,以尽量减少花费在.execute和.fetchone语句上的时间?

答案 根据CL和rocksportrocker提供的答案,我将表格创建声明(简化版)更改为:

致:

在我的测试案例中

  • 文件大小保持不变
  • .executemany INSERT语句从约46秒增加到约69秒
  • .execute SELECT语句从约129秒减少到约5秒
  • .fetchone语句从约183秒减少到约0秒
  • 总时间从约503秒减少到约228秒,为原始时间的45%

其他任何改进都是受欢迎的,希望这可以成为对SQL新的人的一个很好的参考问题。

< P>你考虑在<代码>解决方案< /代码>列中引入索引吗?将增加
.db
文件的插入时间和大小。

数据库在
execute()
fetchone()
调用中完成所有工作


要加快查询速度,必须为查找列编制索引。为了节省空间,您可以使用聚集索引,即将表设为a。

由于文件大小,我删除了大多数索引。sqlite3db的大小大约是专有文件(我猜是压缩文件)的5倍。因此,我只需要4个文件就可以创建约1GB的数据库。这个工具一次将经常用于12-15个文件,大小成了一个问题。我给它一个机会只是为了测试它。我最终得到的不是约250MB的dbs,而是约350MB的dbs。我的主要插入时间从46秒到96秒。但是,我的总时间从503秒到260秒。我不喜欢额外的100MB,但这绝对是一个不错的选择。我可以使用索引编写、比较、删除dbs,然后在没有索引的情况下重写它们,所用的时间比我当前的解决方案要短。非常感谢,我不知道影响会这么大。我将不得不阅读索引,我在SQL方面相当缺乏经验。您也可以考虑将完整的循环<代码>替换为Dig.ItReItMes()中的关键字、VA:<代码> > <代码>选择< /Cord>,每次迭代返回一行。简单的“从表中选择值”的结果会有多大?我问这个问题,因为一次选择返回多个值可能比多次选择迭代快得多。我再次查看了您的代码,您最好在
solution
num
上设置一个组合索引,而不是
solution
上的索引。好吧,一次选择的结果会很小,但表中有大约300k行,我只对其中721个感兴趣。你和@CL在索引表方面是对的。无ROWID也解决了文件大小增加的问题。您是否尝试过进行简单的正则表达式搜索(使用Python或Linux命令grep进行测试)?顺便提一下,第一个问题很好,欢迎!您是否建议使用regexs并完全避免创建.db?如果是这样的话,我没有这样做有三个原因:1)我在比较后保留.db选项,以便查看完整的结果;2) 我在SQL中操作的不同表中有很多链接数据,最后创建了四个视图,总结了开始比较所需的数据;3)我不知道如何使用正则表达式:谢谢你的欢迎!请注意,我们不会把答案放在这个网站的问题里面。如果您有基于先前答案的混合解决方案,则完全可以发布您自己问题的答案,以说明您是如何解决的!(另请注意,如果您提供我们可以在此网站上帮助使用Regex的文件格式,它也是标记之一)在我的表上创建了一个主键(solution,num),并在没有ROWID的情况下添加。这使我的文件大小保持不变,写入时间从约46秒增加到约70秒,但总时间从约500秒减少到约230秒。巨大的进步。我不知道没有ROWID选项,非常感谢!
dict = {(solution_id, num): [db1_val, db2_val, db3_val, db4_val]}
CREATE TABLE table(
solution integer, num integer, ..., value real,
FOREIGN KEY (solution) REFERENCES solution (id),
FOREIGN KEY (num) REFERENCES nums (id)
);
CREATE TABLE table(
solution integer, num integer, ..., value real,
PRIMARY KEY (solution, num),
FOREIGN KEY (solution) REFERENCES solution (id),
FOREIGN KEY (num) REFERENCES nums (id)
) WITHOUT ROWID;