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中查询SQLite数据库与处理pandas.Dataframe一样快_Pandas_Sqlite - Fatal编程技术网

在Python中查询SQLite数据库与处理pandas.Dataframe一样快

在Python中查询SQLite数据库与处理pandas.Dataframe一样快,pandas,sqlite,Pandas,Sqlite,我有一个DB文件,它有一个表,有两列“a”和“b”,大约1100万行 当我将表加载到pandas.Dataframe并执行一个简单的过滤时,如 df = df[ abs(df['a']-df['b']) > 0.0001 ] 处理时间不到500毫秒 但是,当我像这样直接在sqlite3 shell中查询db时 SELECT a, b FROM table WHERE abs(a-b)>0.0001 这个过程大约需要3秒。在我的实际工作中,我需要一个更复杂的查询,它会产生更大的开销

我有一个DB文件,它有一个表,有两列“a”和“b”,大约1100万行

当我将表加载到pandas.Dataframe并执行一个简单的过滤时,如

df = df[ abs(df['a']-df['b']) > 0.0001 ]
处理时间不到500毫秒

但是,当我像这样直接在sqlite3 shell中查询db时

SELECT a, b
FROM table
WHERE abs(a-b)>0.0001
这个过程大约需要3秒。在我的实际工作中,我需要一个更复杂的查询,它会产生更大的开销。实际上,需要以交互方式更改过滤条件,这意味着需要多次查询才能获得最终表


我知道熊猫数据帧在内存中,但表在磁盘上。有没有一种简单的方法可以像pandas中的布尔索引一样快速地在内存中加载表并过滤条目

SQlite确实支持纯内存数据库,请参见此。你需要自己管理持久性。此外,即使是内存中的SQLite数据库也将受益于正确指定的键。在这种情况下,正确与否取决于查询的确切性质。

您可以使用诸如调整or之类的设置,但对于包括sqlite在内的关系数据库,提高查询性能的方法是使用适当的。特别是,Sqlite支持:

在表ABSA-b上创建索引表_idx_abs_a_b; 比较此索引之前和之后的值:

sqlite>创建表fooa,b; sqlite>EXPLAIN查询计划从foo中选择a、b,其中absa-b>0.0001; 查询计划 `-扫描表foo sqlite>在fooabsa-b上创建索引foo_idx_abs_a_b; sqlite>EXPLAIN查询计划从foo中选择a、b,其中absa-b>0.0001; 查询计划 `-使用索引foo\u idx\u abs\u a\u b>搜索表foo? 如果没有索引,它必须扫描整个表并查看每一行。有了索引,它可以直接查找那些大于比较值的行,忽略那些小于或等于的行,如果有许多这样的行,则可以节省大量时间。但是,如果大多数行的条件为真,则索引没有多大好处


另一种选择是在另一列中提前计算absa-b值,并在其上添加索引。即将发布的Sqlite 3.31将为这类内容生成列,但目前的做法是在插入和更新时触发,以使其与a和b值保持同步。

我创建了一个内存数据库,并将其连接到磁盘上。然后我尝试了同样的过滤查询。处理查询的时间为4秒。内存数据库似乎并没有真正提高速度。我不是内存数据库或附加数据库的普通用户。然而,我希望从另一个数据库附加一个表仍然可以在该表的原始磁盘位置上操作。要在内存中操作,您必须将磁盘数据库中的数据插入内存数据库中的表中,并为此操作支付时间成本,然后根据内存数据库中的表进行选择。此外,不能保证SQLite,即使在内存中,也会像Pandas一样快——它们是用于不同目的的不同架构。此外,如果您将数据传输到内存数据库中,我会在那时执行abs计算,并将计算出的数字存储在内存数据库中。这肯定会提高性能。我创建了一个内存中的数据库,然后使用此查询将表复制到它,并将其插入到tab1 select*from attached_db.table中。然后,我再次以与原来问题m相同的方式提问。处理时间仍为4秒。我认为开销来自“WHERE”子句,因为您必须计算1100万行。@nownurian会有所帮助。谢谢您的回答!我按照你的建议创建了一个索引。现在执行时间只有2ms。