首页 > 数据库 >SQLite performance tuning

SQLite performance tuning

时间:2023-04-13 23:58:10浏览次数:54  
标签:SQLite tuning database pragma memory performance size

SQLite performance tuning - Scaling SQLite databases to many concurrent readers and multiple gigabytes while maintaining 100k SELECTs per second - phiresky's blog

 

Scaling SQLite databases to many concurrent readers and multiple gigabytes while maintaining 100k SELECTs per second

JUN 26, 2020 • LAST UPDATE JUL 31, 2022

SQLite is an embedded SQL database. It’s extremely easy to setup, buildable as a single C file with libraries existing for basically all common programming languages. It doesn’t need any server setup or configuration since the SQL logic is run in the host process, and the database consists of only two files you can easily copy or move around. You can still connect to and query the same database concurrently with multiple processes, though only one write operation can happen at the same time.

SQLite is often seen as a toy database only suitable for databases with a few hundred entries and without any performance requirements, but you can scale a SQLite database to multiple GByte in size and many concurrent readers while maintaining high performance by applying the below optimizations.

Run these every time you connect to the DB

Some of these are applied permanently, but others are reset on new connection, so it’s recommended to run all of these each time you connect to the database.

  • Journal Mode

    pragma journal_mode = WAL;

    Instead of writing changes directly to the db file, write to a write-ahead-log instead and regularily commit the changes. This allows multiple concurrent readers even during an open write transaction, and can significantly improve performance.

  • Synchronous Commit

    pragma synchronous = normal;

    or even synchronous=off. The default is full, which means every single update has to wait for FSYNC. Normal is still completely corruption safe in WAL mode, and means only WAL checkpoints have to wait for FSYNC. Off can cause db corruption, though I’ve never had problems. See here: https://www.sqlite.org/pragma.html#pragma_synchronous

  • Temporary files location

    pragma temp_store = memory;

    Stores temporary indices / tables in memory. sqlite automatically creates temporary indices for some queries. Not sure how much this one helps. If your SQLite is creating temporary indices (check with EXPLAIN QUERY PLAN) you should probably create those indexes yourself in any case.

  • Enable memory mapping

    pragma mmap_size = 30000000000;

    Uses memory mapping instead of read/write calls when the database is < mmap_size in bytes. Less syscalls, and pages and caches will be managed by the OS, so the performance of this depends on your operating system. Note that it will not use the amount of physical memory, it will just reserve virtual memory. The OS will then decide which pages are evicted and which stay in memory based on its usual "disk caching" logic. Should be much faster, at least on Linux and if you have a fair amount of memory for your SQLite process. If your database is larger than the given mmap_size, the first part of the database will still be memory mapped, the rest will be handled with read() / write() syscalls.

    If you are on a 32-bit system you can probably only set this to less than 232232 bytes since the size of the virtual memory space is limited.

    Memory mapping can also have implications when there are I/O errors, see the official documentation.

  • Increase the page size

    pragma page_size = 32768;

    This improved performance and db size a lot for me in one project, but it’s probably only useful if you are storing somewhat large blobs in your database and might not be good for other projects where rows are small. For writing queries SQLite will always only replace whole pages, so this increases the overhead of write queries.

Summary

If you’re too lazy to read all the above, just run this on every database connect:

pragma journal_mode = WAL;
pragma synchronous = normal;
pragma temp_store = memory;
pragma mmap_size = 30000000000;

More things that must be run manually

  • Reorganize the database

    pragma vacuum;

    Run once to completely rewrite the db. Very expensive if your database is 100MB+.

  • Re-analyze the database

    pragma optimize;

    To achieve the best long-term query performance without the need to do a detailed engineering analysis of the application schema and SQL, it is recommended that applications run "PRAGMA optimize" (with no arguments) just before closing each database connection. Long-running applications might also benefit from setting a timer to run "PRAGMA optimize" every few hours.https://www.sqlite.org/pragma.html#pragma_optimize

  • Vacuum the database

    pragma auto_vacuum = incremental; -- once on first DB create
    pragma incremental_vacuum; -- regularily

    Probably not useful unless you expect your DB to shrink significantly regularily.

    The freelist pages are moved to the end of the database file and the database file is truncated to remove the freelist pages […]. Note, however, that auto-vacuum only truncates the freelist pages from the file. Auto-vacuum does not defragment the database nor repack individual database pages the way that the VACUUM command does. In fact, because it moves pages around within the file, auto-vacuum can actually make fragmentation worse.https://www.sqlite.org/pragma.html#pragma_incremental_vacuum

Regarding WAL mode

WAL mode has some issues where depending on the write pattern, the WAL size can grow to infinity, slowing down performance a lot. I think this usually happens when you have lots of writes that lock the table so sqlite never gets to doing wal_autocheckpoint. There’s a few ways to mitigate this:

  1. Reduce wal_autocheckpoint interval. No guarantees since all autocheckpoints are passive.
  2. Run pragma wal_checkpoint(full) or pragma wal_checkpoint(truncate) sometimes. With full, the WAL file won’t change size if other processes have the file open but still commit everything so new data will not cause the WAL file to grow. If you run truncate it will block other processes and reset the WAL file to zero bytes. Note that you can run these from a separate process, it will just block other write queries for a bit.

标签:SQLite,tuning,database,pragma,memory,performance,size
From: https://www.cnblogs.com/chinasoft/p/17317000.html

相关文章

  • 为什么 SQLite 一定要用 C 语言来开发?
    SQLite是一种专门为在Unix和类Unix操作系统上运行的Linux服务器应用程序而设计的数据库管理系统,是一种轻量级的关系型数据库管理系统,它适用于许多嵌入式设备和物联网设备。它使用C语言编写,并且是一个开源项目。简单易用:SQLite的语法简单易懂,不需要专业的编程知识,因此适......
  • Android sqlite 数据库查询,插入,删除,更新demo<第1章>
    //20140424创建数据库帮助类DataBaseHelper,继承SQLiteOpenHelper, 1. 编写构造函数,实现数据库创建;publicstaticfinalStringTAG="ListViewActivity";privatestaticintVERSION=1;privatestaticfinalStringTABLE_NAME="user1";privatestaticfinalSt......
  • Oracle SQL优化之STA(SQL Tuning Advisor)
    前言:经常可以碰到优化sql的需求,开发人员直接扔过来一个SQL让DBA优化,然后怎么办?当然,经验丰富的DBA可以从各种方向下手,有时通过建立正确索引即可获得很好的优化效果,但是那些复杂SQL错综复杂的表关联,却让DBA们满头大汗。如下特别介绍一种oracle官方提供的科学优化方法STA,经过实践,不......
  • MULTIINSTRUCT: Improving Multi-Modal Zero-Shot Learning via Instruction Tuning
    指令调优是一种新的学习范式,它可以根据指令指定的任务对预先训练好的语言模型进行微调,在各种自然语言处理任务中显示出良好的零目标性能。然而,对于视觉和多模态任务,它仍然没有被探索。在这项工作中,我们介绍了multiinstruction,这是第一个多模态指令调优基准数据集,由47个不同的多模......
  • unidac 在linux loongxarch64或arm64使用SQLite
    unidacSQLite默认使用静态连接方式,但UNIDAC官方SQLite未提供arm64或loongxarch64静态库,造成linuxfor龙芯或arm64无法使用SQLite,经跟踪unidac源码发现将souce/uniProviders/SQLite/LiteDac.inc添加{$DEFINENOSTATIC}然后安装liteprovider10.lpk就可以。//////////////////......
  • sqlite数据库在close()之后任然不能释放与db文件的连接
    conn.Close();conn.Dispose();在close和dispose后,必须要加上以下两句代码,让垃圾回收机制启动,否则仍不能释放与db文件的连接GC.Collect();GC.WaitForPendingFinalizers();......
  • wxsqlite3 的使用, sqlite3 加密库 编译和测试
     编译库文件:1.用VS2010建立一个控制台工程sqlite3,选项为静态库,不包含预编译头。2.把wxsqlite3-4.5.1.zip\wxsqlite3-4.5.1\sqlite3secure\src下所有的文件复制到工程的工作目录3.把sqlite3.h和sqlite3secure.c加入工程4.工程配置属性AllConfigurations,C/C++,预处理,预......
  • [Javascript] Improve performance of Array.reduce
    Comparetwocodesnippetconstpeople=[{id:1,name:'John',age:45},{id:2,name:"Op",age:32},{id:3,name:"Wade",age:39}]//option1constres=people.reduce((acc,curr)=>{return({......
  • C# opc ua客户端实例源码,带ef6+sqlite
    C#opcua客户端实例源码,带ef6+sqlite。代码有完整的注解,及包括所有的链接库和程序结构思维图。纯学习资料YID:2855638904489888......
  • SQLiteOpenHelper&SharedPreferences练习
    目录结构:packagecom.dc.app;importjava.text.DecimalFormat;importjava.util.Locale;importandroid.app.Activity;importandroid.app.AlertDialog;importandroid.app.Dialog;importandroid.app.Notification;importandroid.app.Notificati......