Sqlite真空命令VACUUM

之前在项目中使用了sqlite数据库,当日志变大时,执行CRUD操作就会变慢

后来尝试删除7天前的记录进行优化

delete from XX_CollectData where CreateTime<='2024-01-24'

发现sqlite文件的大小就没有变化,delete命令只是逻辑删除,所在的文件的字节码仍然还在,优化效果仍不明显。

后来使用真空命令VACUUM,发现文件大小确实变小了。

VACUUM

SQLite Vacuum

VACUUM 命令通过复制主数据库中的内容到一个临时数据库文件,然后清空主数据库,并从副本中重新载入原始的数据库文件。这消除了空闲页,把表中的数据排列为连续的,另外会清理数据库文件结构。

如果表中没有明确的整型主键(INTEGER PRIMARY KEY),VACUUM 命令可能会改变表中条目的行 ID(ROWID)。VACUUM 命令只适用于主数据库,附加的数据库文件是不可能使用 VACUUM 命令。

如果有一个活动的事务,VACUUM 命令就会失败。VACUUM 命令是一个用于内存数据库的任何操作。由于 VACUUM 命令从头开始重新创建数据库文件,所以 VACUUM 也可以用于修改许多数据库特定的配置参数。

相关测试程序类【C#代码】

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;
using System.Linq;
using System.Text;

namespace SnakeSqliteDemo
{
    /// <summary>
    /// 作者:斯内科
    /// 时间:2024-01-24
    /// 功能:sqlite数据库操作类
    /// </summary>
    public class SqliteDbHelper
    {
        /// <summary>
        /// 连接字符串
        /// </summary>
        private string m_strConnectString = string.Empty;

        /// <summary> 
        /// 构造函数 
        /// </summary> 
        /// <param name="strDbPath">SQLite数据库文件路径</param> 
        public SqliteDbHelper(string strDbPath)
        {
            this.m_strConnectString = "Data Source=" + strDbPath;
        }

        /// <summary> 
        /// 创建SQLite数据库文件 
        /// </summary> 
        /// <param name="strDbPath">要创建的SQLite数据库文件路径</param> 
        /// <param name="strdbTableCreateString">要创建的SQLite数据库表格</param> 
        public static void CreateDB(string strDbPath, string strdbTableCreateString)
        {
            using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + strDbPath))
            {
                connection.Open();
                using (SQLiteCommand command = new SQLiteCommand(connection))
                {
                    command.CommandText = strdbTableCreateString;
                    command.ExecuteNonQuery();
                }
            }
        }

        /// <summary> 
        /// 对SQLite数据库执行增删改操作,返回受影响的行数。 
        /// </summary> 
        /// <param name="strSql">要执行的增删改的SQL语句</param> 
        /// <param name="parameters">执行增删改语句所需要的参数,参数必须以它们在SQL语句中的顺序为准</param> 
        /// <returns>返回受影响的行数</returns> 
        public int ExecuteNonQuery(string strSql, SQLiteParameter[] parameters, bool IsDelete = false)
        {
            try
            {
                int intAffectedRows = 0;
                using (SQLiteConnection connection = new SQLiteConnection(m_strConnectString))
                {
                    connection.Open();
                    using (DbTransaction transaction = connection.BeginTransaction())
                    {
                        using (SQLiteCommand command = new SQLiteCommand(connection))
                        {
                            command.CommandText = strSql;
                            if (parameters != null)
                            {
                                command.Parameters.AddRange(parameters);
                            }
                            intAffectedRows = command.ExecuteNonQuery();
                        }
                        transaction.Commit();
                        if (IsDelete)
                        {
                            //sqlite 真空命令,文件压缩:VACUUM 命令通过复制主数据库中的内容到一个临时数据库文件,然后清空主数据库,并从副本中重新载入原始的数据库文件。
                            //这消除了空闲页,把表中的数据排列为连续的,另外会清理数据库文件结构。
                            using (SQLiteCommand command = new SQLiteCommand(connection))
                            {
                                command.CommandText = "VACUUM";
                                command.ExecuteNonQuery();
                            }
                        }
                    }
                }
                return intAffectedRows;
            }
            catch(Exception ex)
            {
                Console.WriteLine("执行sql语句异常," +ex.Message + "\r\n详细sql语句为:" + strSql);
                return -1;
            }
        }

        public int ExecuteNonQueryByDic(string strSql, Dictionary<string, object> dicParams)
        {
            try
            {
                int intAffectedRows = 0;
                using (SQLiteConnection connection = new SQLiteConnection(m_strConnectString))
                {
                    connection.Open();
                    using (DbTransaction transaction = connection.BeginTransaction())
                    {
                        using (SQLiteCommand command = new SQLiteCommand(connection))
                        {
                            command.CommandText = strSql;
                            if (dicParams != null && dicParams.Count > 0)
                            {
                                command.Parameters.Clear();
                                foreach (string parameterName in dicParams.Keys)
                                {
                                    command.Parameters.AddWithValue(parameterName, dicParams[parameterName]);
                                }
                            }
                            intAffectedRows = command.ExecuteNonQuery();
                        }
                        transaction.Commit();
                    }
                }
                return intAffectedRows;
            }
            catch(Exception ex)
            {
                Console.WriteLine("执行sql语句异常," + ex.Message + "\r\n详细sql语句为:" + strSql);
                return -1;
            }
        }

        /// <summary> 
        /// 执行一个查询语句,返回一个关联的SQLiteDataReader实例 
        /// </summary> 
        /// <param name="strSql">要执行的查询语句</param> 
        /// <param name="parameters">执行SQL查询语句所需要的参数,参数必须以它们在SQL语句中的顺序为准</param> 
        /// <returns>返回SQLiteDataReader</returns> 
        public SQLiteDataReader ExecuteReader(string strSql, SQLiteParameter[] parameters)
        {
            SQLiteConnection connection = new SQLiteConnection(m_strConnectString);
            SQLiteCommand command = new SQLiteCommand(strSql, connection);
            if (parameters != null)
            {
                command.Parameters.AddRange(parameters);
            }
            connection.Open();
            return command.ExecuteReader(CommandBehavior.CloseConnection);
        }

        /// <summary> 
        /// 执行一个查询语句,返回一个包含查询结果的DataTable 
        /// </summary> 
        /// <param name="strSql">要执行的查询语句</param> 
        /// <param name="parameters">执行SQL查询语句所需要的参数,参数必须以它们在SQL语句中的顺序为准</param> 
        /// <returns>返回数据表</returns> 
        public DataTable ExecuteDataTable(string strSql, SQLiteParameter[] parameters)
        {
            using (SQLiteConnection connection = new SQLiteConnection(m_strConnectString))
            {                
                using (SQLiteCommand command = new SQLiteCommand(strSql, connection))
                {
                    if (parameters != null)
                    {
                        command.Parameters.AddRange(parameters);
                    }
                    SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
                    DataTable data = new DataTable();
                    adapter.Fill(data);
                    return data;
                }
            }

        }

        public DataTable GetDataTable(string strSql, Dictionary<string, object> dicParams)
        {
            using (SQLiteConnection connection = new SQLiteConnection(m_strConnectString))
            {
                using (SQLiteCommand command = new SQLiteCommand(strSql, connection))
                {
                    if (dicParams != null && dicParams.Count > 0)
                    {
                        command.Parameters.Clear();
                        foreach (string parameterName in dicParams.Keys)
                        {
                            command.Parameters.AddWithValue(parameterName, dicParams[parameterName]);
                        }
                    }
                    SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
                    DataTable data = new DataTable();
                    adapter.Fill(data);
                    return data;
                }
            }
        }

        public DataSet ExcuteDataSet(string strSql)
        {
            DataSet ds = new DataSet("MyDataSet");
            using (SQLiteConnection connection = new SQLiteConnection(m_strConnectString))
            {
                using (SQLiteCommand command = new SQLiteCommand(strSql, connection))
                {                    
                    SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
                    adapter.Fill(ds);
                    return ds;
                }
            }           
        }

        /// <summary> 
        /// 执行一个查询语句,返回查询结果的第一行第一列 
        /// </summary> 
        /// <param name="strSql">要执行的查询语句</param> 
        /// <returns>返回第一行第一列的值</returns> 
        public object ExecuteScalar(string strSql)
        {
            try
            {
                using (SQLiteConnection connection = new SQLiteConnection(m_strConnectString))
                {
                    connection.Open();
                    using (SQLiteCommand command = new SQLiteCommand(strSql, connection))
                    {
                        return command.ExecuteScalar(); 
                    }
                }
            }
            catch
            {
                throw;
            }
        }

        public int ExecuteScalarInt(string strSql)
        {
            object oRes = ExecuteScalar(strSql);
            return oRes == null ? 0 : Convert.ToInt32(oRes);
        }

        /// <summary> 
        /// 查询数据库中的所有数据类型信息 
        /// </summary> 
        /// <returns>返回数据表</returns> 
        public DataTable GetSchema()
        {
            using (SQLiteConnection connection = new SQLiteConnection(m_strConnectString))
            {
                connection.Open();
                DataTable data = connection.GetSchema("TABLES");
                connection.Close();
                return data;
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/346512.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

构建库函数雏形(以GPIO为例)

构建库函数雏形 进行外设结构体定义构建置位和复位函数进行库函数的自定义 step I&#xff1a; \textbf{step I&#xff1a;} step I&#xff1a; 对端口进行输出数据类型枚举 step II&#xff1a; \textbf{step II&#xff1a;} step II&#xff1a;对端口进行结构化描述 step…

76.Go分布式ID总览

文章目录 简介一&#xff1a;UUID二、雪花算法三&#xff1a;Leaf-snowflake四&#xff1a;数据库自增ID五&#xff1a;使用Redis实现分布式ID生成六&#xff1a;使用数据库分段&#xff08;Leaf-segment&#xff09;七 &#xff1a;增强版Leaf-segment八&#xff1a;Tinyid九&…

Linux破解密码

破解root密码&#xff08;Linux 7&#xff09; 1、先重启——e 2、Linux 16这一行 末尾加rd.break&#xff08;不要回车&#xff09;中断加载内核 3、再ctrlx启动&#xff0c;进入救援模式 4、mount -o remount&#xff0c;rw /sysroot/——&#xff08;mount挂载 o——opti…

第四十周:文献阅读+GAN

目录 摘要 Abstract 文献阅读&#xff1a;结合小波变换和主成分分析的长短期记忆神经网络深度学习在城市日需水量预测中的应用 现有问题 创新点 方法论 PCA&#xff08;主要成分分析法&#xff09; DWT&#xff08;离散小波变换&#xff09; DWT-PCA-LSTM模型 研究实…

【sgTree】自定义组件:加载el-tree树节点整棵树数据,实现增删改操作。

特性 可以自定义主键、配置选项支持预定义节点图标&#xff1a;folder文件夹|normal普通样式多个提示文本可以自定义支持动态接口增删改节点可以自定义根节点id可以设置最多允许添加的层级深度支持拖拽排序&#xff0c;排序过程还可以针对拖拽的节点深度进行自定义限制支持隐藏…

运用ETLCloud快速实现数据清洗、转换

一、数据清洗和转换的重要性及传统方式的痛点 1.数据清洗的重要性 数据清洗、转换作为数据ETL流程中的转换步骤&#xff0c;是指在数据收集、处理、存储和使用的整个过程中&#xff0c;对数据进行检查、处理和修复的过程&#xff0c;是数据分析中必不可少的环节&#xff0c;对…

人工智能技术应用:引领未来的智能时代

随着科技的日新月异&#xff0c;人工智能&#xff08;AI&#xff09;技术应用正逐渐成为我们生活中不可或缺的一部分。从智能手机中的语音助手到无人驾驶汽车&#xff0c;人工智能技术正在推动世界进入一个智能时代。本文将重点探讨人工智能技术在生活、医疗、交通等领域的应用…

Redis(秒杀活动、持久化之RDB、AOF)

目录 秒杀活动 一、测压工具jmete的使用 二、java实现秒杀活动 1、myseckillcontroller 2、先启动pos请求添加商品&#xff0c;再启动jmeter进行压测 Redis持久化 一 、Redis持久化之RDB 1.RDB是什么 2. 备份是如何执行的 3.Fork 4. RDB持久化流程 5. dump.rdb文件 6…

03-TiDB-单机上模拟部署生产环境集群

1、安装集群cluster组件 tiup cluster # 已安装的可以更新 # tiup update --self && tiup update cluster 2、修改主机sshd 服务的连接数限制 vim /etc/ssh/sshd_config # MaxSessions 20#重启 sshd 服务&#xff1a; service sshd restart 3、设置集群配置文件top…

一个监控小技巧,巧妙破解超低温冰箱难题!

在当今科技飞速发展的时代&#xff0c;超低温冰箱监控系统以其在各行各业中关键的温度控制和环境监测功能而备受关注。 超低温环境对于存储生物样本、药品和其他温度敏感物品至关重要&#xff0c;而监控系统则提供了实时、精准的环境数据&#xff0c;确保这些物品的质量和安全性…

Ubuntu apt update提示:GPG 缺少公钥解决方法

Ubuntu 运行: sudo apt update #or sudo apt-get update提示&#xff1a;GPG 缺少公钥以及404 Not Found&#xff0c;如下面所示&#xff0c;有mirror.bwbot.org 和ppa.launchpadcontent.net两个源出现问题。 好多网友用后面的方法解决 真正解决&#xff1a;gpg --verify sig:…

bash 5.2中文修订4

Compound Commands 复合命令 复合命令是 shell 编程语言的结构。每个构造都以保留字或控制运算符开始&#xff0c;并以相应的保留字或运算符终止。与复合命令关联的任何重定向&#xff08;请参阅 Redirections &#xff09;都适用于该复合命令中的所有命令&#xff0c;除非显式…

web蓝桥杯真题--14、关于你的欢迎语

介绍 营销号&#xff0c;有时候需要一些特定的欢迎语&#xff0c;但针对特定的用户&#xff0c;我们希望可以个性化一点。本题需要在项目文件中修改代码存在的问题&#xff0c;实现根据模版生成特定用户的欢迎语。 准备 本题已经内置了初始代码&#xff0c;打开实验环境&…

Unity读书系列《Unity3D游戏开发》——拓展编辑器(一)

文章目录 前言一、扩展Project视图1、右键扩展菜单&#xff08;Asset&#xff09;2、监听事件3、拓展布局 二、扩展Hierarchy视图1、拓展菜单&#xff08;GameObject&#xff09;2、拓展布局3、重写菜单 三、扩展Inspector视图1、扩展原生组件2、扩展继承组件 四、扩展Scene视图…

redis-持久化-1

Redis 提供了2个不同形式的持久化方式。 RDB&#xff08;Redis DataBase&#xff09; AOF&#xff08;Append Of File&#xff09; 一、Redis持久化之RDB 1.什么是RDB 在指定的时间间隔内将内存中的数据集快照写入磁盘&#xff0c; 也就是行话讲的Snapshot快照&#xff0c…

Windows10上通过MSYS2编译FFmpeg 6.1.1源码操作步骤

1.从github上clone代码&#xff0c;并切换到n6.1.1版本&#xff1a;clone到D:\DownLoad目录下 git clone https://github.com/FFmpeg/FFmpeg.git git checkout n6.1.1 2.安装MSYS2并编译FFmpeg源码: (1).从https://www.msys2.org/ 下载msys2-x86_64-20240113.exe &#…

JS高频面试题(下)

11. 线程和进程的区别 进程是资源分配的最小单元&#xff0c;线程是代码执行的最小单元。 一个应用程序可能会开启多个进程&#xff0c;进程之间数据不共享&#xff0c;一个进程内部可以开启多个线程&#xff0c;线程之间的数据可以共享的&#xff0c;所以多线程的情况下&…

Qt/QML编程之路:ListView实现横排图片列表的示例(40)

ListView列表,在QML中使用非常多,排列一个行,一个列或者一个表格,都会用到ListView。 ListView显示从内置QML类型(如ListModel和XmlListModel)创建的模型中的数据,或在C++中定义的从QAbstractItemModel或QAbstract ListModel继承的自定义模型类中的数据。 ListView有一…

搭建通讯猫类似的TCP服务端

最近需要一个公网的TCP服务端平台来做4G模组的发包测验&#xff0c;通讯猫(http://www.tongxinmao.com/App/Detail/id/1)貌似使用不了&#xff0c;就干脆在自己的腾讯云上搭建了简单的TCP服务端。 我们搭建可以在服务器上使用Python、Java、C#等语言自行编写服务器程序。 目前是…

element-ui 树形控件 通过点击某个节点,遍历获取上级的所有父节点和本身节点

1、需求&#xff1a;点击树形控件的某个节点&#xff0c;需要拿到它上级的所有父节点进行操作 2、代码&#xff1a; 树形控件代码 <el-tree:data"deptOptions"node-click"getVisitCheckedNodes"ref"target_tree_Speech"node-key"id&qu…