如何加快SQLite的写入速度

X366ING 2019-12-18 01:15:22
小弟最近在优化SQLite的写入速度,原代码如下

public class DatabaseManager : IDisposable
{
private SQLiteConnection dbConnection = null;

private DatabaseManager(string connectionString)
{
dbConnection = new SQLiteConnection(connectionString);
dbConnection.Open();
}

public void Dispose()
{
dbConnection.Close();
dbConnection = null;
}

public int ExecuteNoQuery(string command)
{
int nResult = -1;
try
{
using (SQLiteCommand dbCommand = dbConnection.CreateCommand())
{
dbCommand.CommandText = command;
nResult = dbCommand.ExecuteNonQuery();
}
}
catch (Exception e)
{
LogError("Error occurs during execute sql no result query, error message: ", e.Message);
}
return nResult;
}
}


搜索百度和谷歌,了解到添加事务可以提高数据库的写入效率。 但事务针对的应该是大数据的批量写入。而我每次写入数据库的都是很琐碎的小数据,比如每次写入一行日志,而且我无法预见到下一次写入是什么时候。这样就无法使用事务进行优化。我尝试在类里面加一个timer,定时去提交事务,然后在创建一个新的事务。感觉这种做法很笨,请教各位大牛有没有其他的方法优化数据库的写入。对于这种频繁的写入小数据的情况,该怎么优化?
...全文
574 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
datafansbj 2019-12-19
  • 打赏
  • 举报
回复
引用 4 楼 X366ING 的回复:
[quote=引用 2 楼 datafansbj 的回复:] 对于日志这种要求不是特别高的数据,可以考虑先存到内存中,然后批量保存到数据库(可以定时保存、超过阀值保存两种方式结合),这样可以提高性能。缺点是有延迟,即查询日志时可能最近的还没有保存到数据库中。
之前确实考虑过超过阈值保存这种方式,但是考虑到延迟的问题,就放弃了。[/quote] 必须定时和阀值结合起来使用,否则延迟太大(不到阀值就不保存,谁也受不了)。定时也可使用 While ... Sleep 代替。
FainSheeg 2019-12-19
  • 打赏
  • 举报
回复
你都服务端了,还在这用sqlite,还优化,sqlite是搞单机才用的。你确定你想明白 了?抛开这个不说,你写个日志还能写到sqlite都搞不过来了?那我觉得你得考虑这么高频的日志是否有必要了,绝对是已经影响的程序的主业务的性能的了。
andy_wanhl 2019-12-18
  • 打赏
  • 举报
回复
C# 操作SQLite示例源码, 你按照例子做,在批量插入和批量替换的时候,一定要用事务。 这套配置无须优化,按示例使用即可,已经是使用在大型项目产品中,抽出来的。 然后就是,你搞清楚了SQLite本身的使用范围没有?它只是一个本地缓存数据库,是没有多用户连接的,是否真的适合你当前项目需求? https://download.csdn.net/download/andy_wanhl/12007418
andy_wanhl 2019-12-18
  • 打赏
  • 举报
回复
不用想,SQLite的批量insert,批量replace必须用事务处理,不然很慢的。
/// <summary>
        /// SQLite数据库批量操作,要使用事务处理,效率可提升。
        /// </summary>
        /// <param name="info"></param>
        public static void InsertStudent(List<Student> info)
        {
            using (SQLiteConnection conn = DbUtils.getConnection())
            {
                conn.Open();
                IDbTransaction transaction = conn.BeginTransaction();
                try
                {
                    //Sql语句
                    const string sql = @"insert into student(stuName,age) values(@stuName,@age)";
                    foreach (Student parms in info)
                    {
                        conn.Execute(sql, parms);
                    }
                    transaction.Commit();//提交事务
                }
                catch (Exception ex)
                {
                    transaction.Rollback();//回滚事务
                }
            }
        }
X-i-n 2019-12-18
  • 打赏
  • 举报
回复
碰到问题不能拍脑门啊。你想提高性能,那么当前性能如何,希望达到何种性能?害怕数据库碰到瓶颈,那么现在达到瓶颈了吗?具体的瓶颈数值是多少?距离瓶颈还有多少?而不是灵光一闪,虽然不知道现状,不知道预期优化目标,不知道优化空间有多少,我就是要做优化。 如果你想获得最佳性能,那么应该从数据库选型开始,并发多少,数据量多少,sqlite是否满足。当各种条件都考虑到,sqlite成为最佳选择的时候,再去谈sqlite本身的优化。
datafansbj 2019-12-18
  • 打赏
  • 举报
回复
SQLite 确实有这个问题,不使用事务性能较差,建议你使用最新版本的 SQLLite 测试一下。
by_封爱 版主 2019-12-18
  • 打赏
  • 举报
回复
其实你是为了"做"而去"做". 你没有考虑实际需求. 比如你说你频繁. 那么我问你如何频繁 并发多少 你也没有详细数据. 然后就是你说不能让数据库读写成为瓶颈. 我们假设你是insert update.那么你所谓的瓶颈在哪? 你遇到了吗? 是哪种场景遇到的? 是执行超时了? 还是报错了? sqlite不太清楚.. 如果是mysql或者是mssql 这种代码 基本没啥问题.. 循环插入个万八的 也不会报错.. 所以还是要针对具体需求具体讨论. 就现在来说,你的需求就是快速执行一条sql语句. 一共就那么几行代码.. 我觉得没啥优化的空间了.换硬件解决吧.
X366ING 2019-12-18
  • 打赏
  • 举报
回复
引用 3 楼 by_封爱 的回复:
一次一行数据insert 或者update也不需要事务啊 干就完了. 另外你既然说到频繁.. 那么具体有多"频繁"呢 一秒钟有1W条 ?
每次Insert或者Update,其实都有开启一个自动事务,只不过SQLite隐藏了这个细节。 对于一般的客户端程序,一次一行数据其实足够了,但程序在服务器端,我希望能今天提高服务器端的性能,最起码不能让数据库的读写成为瓶颈。
X366ING 2019-12-18
  • 打赏
  • 举报
回复
引用 2 楼 datafansbj 的回复:
对于日志这种要求不是特别高的数据,可以考虑先存到内存中,然后批量保存到数据库(可以定时保存、超过阀值保存两种方式结合),这样可以提高性能。缺点是有延迟,即查询日志时可能最近的还没有保存到数据库中。
之前确实考虑过超过阈值保存这种方式,但是考虑到延迟的问题,就放弃了。
by_封爱 版主 2019-12-18
  • 打赏
  • 举报
回复
一次一行数据insert 或者update也不需要事务啊 干就完了. 另外你既然说到频繁.. 那么具体有多"频繁"呢 一秒钟有1W条 ?
datafansbj 2019-12-18
  • 打赏
  • 举报
回复
对于日志这种要求不是特别高的数据,可以考虑先存到内存中,然后批量保存到数据库(可以定时保存、超过阀值保存两种方式结合),这样可以提高性能。缺点是有延迟,即查询日志时可能最近的还没有保存到数据库中。
  • 打赏
  • 举报
回复
引用
这是因为如果数据库更新操作没有使用事务处理,则每次Update操作都会引起数据库写盘一次。使用事务处理后,更新只在内存缓冲区内进行,执行CommitTrans时才将所有修改一次写回到磁盘中
百度的一种说法,如果成立,像你说的,每次写入一行日志这种,根本就没有必要使用事务吧

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧