Python SQLite-缓慢更新记录

Python SQLite-缓慢更新记录,python,sqlite,Python,Sqlite,我有一个脚本,它将存储在数据库中的日期从Unix时间(历元)转换为人类可读的格式。有30000条记录。 从数据库中提取数据、转换数据并将其打印到屏幕上的速度非常快。但是,要从数据库中提取数据、转换数据并执行“update”语句来更新记录,速度非常慢。 对于我拥有的30000条记录,是否需要优化以下代码以加快此过程 cur.execute('select Atime from Hash where Atime like (?) ', (test,)) results = cur.f

我有一个脚本,它将存储在数据库中的日期从Unix时间(历元)转换为人类可读的格式。有30000条记录。
从数据库中提取数据、转换数据并将其打印到屏幕上的速度非常快。但是,要从数据库中提取数据、转换数据并执行“update”语句来更新记录,速度非常慢。
对于我拥有的30000条记录,是否需要优化以下代码以加快此过程

    cur.execute('select Atime from Hash where Atime like (?) ', (test,))
    results = cur.fetchall()
    for row in results:
        convertedtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime((float(row[0]))))
        print convertedtime
        cur.execute('Update Hash set Atime = (?) where Atime = (?)', (convertedtime, row[0]))
    con.commit()

con.commit()

主要的性能问题是从SQLite中提取数据,将其加载到Python中,用Python进行转换,然后将其返回数据库一次一个日期。这永远不会有效率

相反。看起来像是
atime
是Unix时代

update hash set atime = datetime(atime, 'unixepoch', 'localtime');
但是您可能不想在本地时区存储日期。时区变得复杂,还有夏时制,它有缺失和重叠的时间。。。这只会让人流泪。您肯定不想在本地时区中存储日期时间,而不指明该时区是什么

除非您有很好的理由,否则请将其存储为UTC

update hash set atime = datetime(atime, 'unixepoch');

通常,如果您想做SQLite不支持的事情,创建一个用户定义的函数,并在查询中使用它。这将比使用内置SQLite函数效率更低,但比选择、转换和更新效率更高

它看起来像这样

def epoch_to_iso8601(epoch):
    return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime((float(epoch))))

con.create_function("epoch_to_iso8601", 1, epoch_to_iso8601)
然后您可以在查询中使用
epoch\u to_iso8601

update hash set atime = epoch_to_iso8601(atime);
请注意,这与存储过程不同。因为没有SQLite服务器,所以所有代码都在进程中运行,此函数是针对每个进程的


这里真正的问题是将日期时间存储为字符串。这使得他们工作起来既慢又笨拙。这意味着您必须选择一种格式。这意味着您必须解析该格式才能使用它。这意味着您不能使用内置的SQLite日期和时间函数(尽管它们是稀疏的)

实际上,您需要做的是将
atime
保留为Unix时代,并根据每个查询的需要对其进行格式化

select datetime(atime, 'unixepoch') from hash;
幸运的是,SQLite的类型非常松散,它会为您将文本
atime
字段转换为数字,尽管它会导致性能和存储损失


理想情况下,您希望将
atime
更改为使用
datetime
类型,但在SQLite中这很困难。它不支持删除或修改现有列。相反,您必须将数据转储到表中,重新创建表,然后导入数据。这应该非常快,只有30000条记录

切换到CSV模式,将输出发送到文件,然后选择所有内容

sqlite> .mode csv hash
sqlite> .output hash.out
sqlite> select * from hash;
删除现有表,并以相同的方式重新创建它,但使用
atime
作为
datetime

sqlite> drop table hash;
sqlite> create table hash ( atime datetime, and the other columns );
导入转储文件

sqlite> .import hash.out hash

这是否有任何改变:db文件有多大?您可以尝试将其全部导入pandas,然后再导出到sqlite。可能是因为该字段没有索引?什么类型是
Atime
?这似乎是一个文本字段,这是一个问题。我已经关闭了Pragma Synchronous,并将Atime字段更改为NUMERIC,没有任何更改感谢信息伙伴-我将查看并进行一些测试,然后返回报告!感谢您的帮助-我最终使用了以下命令:cur.execute(“更新Hash SET Atime=datetime(Atime,(?)”,('unixepoch'))----效果非常好!