简体   繁体   English

C#中的SQLIte内存使用情况

[英]SQLIte memory usage in C#

I have a simple sqlite database with only one table and 7-8 string fields with ~2.000.000 records. 我有一个简单的sqlite数据库,其中只有一个表和7-8个带有〜2.000.000条记录的字符串字段。 Database file on disk is about 450-500mb... 磁盘上的数据库文件约为450-500mb ...

When i open db file in my c# app and execute simple "select * from tbl" query, computer memory usage goes to 3gb. 当我在C#应用程序中打开db文件并执行简单的“ select * from tbl”查询时,计算机内存使用量将达到3gb。

Here is code i'm using to select data from database: 这是我用来从数据库中选择数据的代码:

        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)
        {
        }

I tried same thing with mysql5 db and memory usage is normal for database of that size. 我用mysql5 db尝试了同样的事情,并且该大小的数据库的内存使用情况正常。 edit: I tried to load same sqlite database with Delphi XE5 and it uses only ~600mb of memory. 编辑:我试图用Delphi XE5加载相同的sqlite数据库,它仅使用〜600mb的内存。

Is there any way to avoid this? 有什么办法可以避免这种情况?

This is not an authoritative answer on this but I suspect the following is the cause of what you see. 这不是权威的答案,但我怀疑以下是您所看到的原因。

SQLite is an in-process database management system. SQLite是一个进程内数据库管理系统。 As such, when you perform that query which selects all records in your 2,000,000 rows table you are essentially loading all that data in memory complete with the overhead that comes from whatever index data structures SQLite uses to reference the data. 这样,当您执行查询以选择2,000,000行表中的所有记录的查询时,实际上是将所有数据加载到内存中,而这些开销完全来自SQLite用于引用数据的任何索引数据结构。

Contrast that with MySQL which runs as a separate process. 与此相反,MySQL是作为独立进程运行的。 Most likely when you send a SELECT * FROM .. query to MySQL via the MySQL data access driver it doesn't really send back all the data at once but instead you're only getting results back gradually, as you read the next record via a DataReader. 当您通过MySQL数据访问驱动程序将SELECT * FROM ..查询发送到MySQL时,很可能并不会一次发送回所有数据,而是通过逐步读取下一条记录而逐渐返回结果一个DataReader。

I encountered this same problem before with C#.net framework 4.0 and here was my observations. 在C#.net Framework 4.0之前,我遇到了相同的问题,这是我的观察结果。

if you're doing a lot of process on the SQLite at the same time(using threads) you will create a big overhead because SQLite locks the whole database because it can only handle one process at a time. 如果您同时(使用线程)在SQLite上执行大量进程,则会造成很大的开销,因为SQLite锁定整个数据库,因为它一次只能处理一个进程。

the workaround I came to solve this problem was to dedicated myself on using transaction during CRUD operations and using prepared statements. 我要解决此问题的变通办法是专注于在CRUD操作期间使用事务和使用准备好的语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM