Python SQLite真的有用吗? - longlongwood/blog GitHub Wiki

SQLite是个很简单的数据库,一个文件就可以搞定,存储上千万行的数据也没问题,图形界面程序有很多,管理很方便,用Python可以编程操作,也很简单,一切都似乎很完美。

我导入了几千万行的数据进SQLite,然后查询、统计什么的都没问题,很好用。可是后来,事情发生了变化……

首先,SQLite并不仅仅是单文件那么简单。 官方文档介绍了多种临时文件:https://sqlite.org/tempfiles.html

这个文档最后提到临时目录在Windows系统中是通过 PRAGMA temp_store_directory; PRAGMA temp_store_directory = 'directory-name'; 指定或者通过 GetTempPath() 系统接口得到,再查一下,第一种情况,那个参数已经被标记为废弃,现在不用了,那就只剩下第二种了,第二种的解释是: The GetTempPath function gets the temporary file path as follows:

  1. The path specified by the TMP environment variable.
  2. The path specified by the TEMP environment variable, if TMP is not defined.
  3. The current directory, if both TMP and TEMP are not defined.

首先用TMP环境变量,找不到就用TEMP环境变量,再找不到就用当前目录。

看来只能修改用户变量了,问题是,一改这里,其他程序的临时目录都会改,不能单独为SQLite指定临时目录。

在执行某些查询或者执行VACUUM命令时,它会在系统的临时目录生成很大的临时文件,如果你是默认的临时目录,而C盘的空间又不是很多的时候,查询或命令会最终失败。这时候,要么释放C盘空间,让它有足够多的位置放临时文件,要么修改临时目录所在的位置。经过测试,它会通过用户环境变量TMP获取临时目录位置,默认情况下,这个变量的值与TEMP是一样的,临时修改TMP变量的值,让它指向容量足够的硬盘,工作完成后把它修改为TEMP一样的值即可,否则以后其他程序的临时文件也会放在那里。修改后必须注销当前用户再重新登录才会生效。

第二,性能问题。

插入的性能问题已经有人做过测试,逐条插入是很慢的,要批量插入才行,我通过python用executemany插入过超过1000万条数据,速度还可以。

没想到居然遇到了DROP TABLE的问题,删掉一个表,看起来应该很简单的事情,居然会那么慢。

经过多番尝试,发现在SQLite里操作大表,速度会很慢,操作小表,速度很快。大表既包括行数多的表,也包括列数多的表,对于这些表来说,无论是DROP TABLE,UPDATE都会很慢,但SELECT似乎不算慢。

对于单个文件很大的数据库,做VACUUM操作会非常占用空间和时间,临时文件的大小与原文件大小一样,在系统临时目录生成完一个文件后,还会在当前目录生成一个存储过程文件,也是很大,这两个文件的生成过程非常耗时,所以没什么必要的时候,不要往数据库里塞一大堆东西,然后全部删除,留下大量垃圾空间,应该塞一个,不用马上删除,再塞下一个,这样就可以充分利用里面删除第一个之后留下的空间,不会把数据库文件撑大。

⚠️ **GitHub.com Fallback** ⚠️