我有一个简单的sqlite数据库,只有一个表和7-8个字符串字段,带有~2.000.000条记录。磁盘上的数据库文件大约是450-500mb ......
当我在c#app中打开db文件并执行简单的“select * from tbl”查询时,计算机内存使用率达到3gb。
以下是我用于从数据库中选择数据的代码:
DataSet ds = new DataSet();
dataGridView1.DataSource = null;
string s = Cstr();
try
{
SQLiteConnection conn = new SQLiteConnection(s);
SQLiteCommand command = new SQLiteCommand(conn);
command.CommandText = "select * from log;";
conn.Open();
command.ExecuteReader();
var da = new SQLiteDataAdapter(command.CommandText, conn);
da.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
conn.Close();
GC.Collect();
}
catch (Exception)
{
}
我用mysql5 db尝试了同样的事情,对于那个大小的数据库,内存使用是正常的。 编辑: 我试图用Delphi XE5加载相同的sqlite数据库,它只使用~600mb的内存。
有什么方法可以避免这种情况吗?
答案 0 :(得分:3)
这不是一个权威的答案,但我怀疑以下是你所看到的原因。
SQLite是一个进程内数据库管理系统。因此,当您执行选择2,000,000行表中所有记录的查询时,您实际上是在内存中加载所有数据,而这些数据来自SQLite用于引用数据的任何索引数据结构。
与MySQL相比,它作为一个单独的进程运行。最有可能当您通过MySQL数据访问驱动程序向MySQL发送SELECT * FROM ..
查询时,它并不会立即发回所有数据,而是您只是逐渐收到结果,因为您读取< / em>通过DataReader的下一条记录。
答案 1 :(得分:0)
我在使用C#.net framework 4.0之前遇到过同样的问题,这是我的观察结果。
如果你在SQLite上同时进行大量的处理(使用线程),你将会产生很大的开销,因为SQLite会锁定整个数据库,因为它一次只能处理一个进程。
解决这个问题的解决方法是专注于在CRUD操作和使用预准备语句时使用事务。