`

基于FMDB-SQLite的App数据库性能优化

 
阅读更多

 

1)如果数据库配置成为串行模式:sqlite3_config(SQLITE_CONFIG_SERIALIZED)

     此模式下可以多个线程使用一个数据库连接,但显然对数据库的操作很慢;

     所以建议:

     数据库配置成多线程模式:sqlite3_config(SQLITE_CONFIG_MULTITHREAD)

     此模式下多个线程必须各自使用自己的数据库连接,多个连接对SQLite的操作不用担心,因为SQLite是线程安全的。

     但是这样仍然不好,线程数过多(上百左右个线程发起数据操作)会导致数据库压力大,尤其是有事务操作时会发起很多事务请求,这时所有的带事务请求都会卡在beginTransaction,严重影响性能,使得整个App中所有对数据库数据有请求的页面一直loading,虽然界面不会卡死,但是数据一直出不来;

     所以,采用FMDB queue(其实就是GCD串行队列),因为FMDB queue串行队列,所以所有的数据操作包括事务都是串行执行的,所有多线程发起的数据库操作都被异步放到了这个队列里,不会卡住UI,也不会有数据库事务并发问题;

2)事务中有大数据量(几千条)条件查询(注意是条件查询),然后再数据更新和插入

     按1)优化后也有可能性能还是慢的情况,也就是如2)题,这种查询特别慢,严重影响了事务的执行;所以尽量避免在事务中有大数据量条件查询;

3)最后,把数据库的WAL模式开启,这样数据库的写操作很快,而且可以对数据并发写和读取;

     WAL is significantly faster in most scenarios.

     WAL provides more concurrency as readers do not block writers and a writer does not block readers. Reading and writing can proceed concurrently.

     Disk I/O operations tends to be more sequential using WAL.

     WAL uses many fewer fsync() operations and is thus less vulnerable to problems on systems where the fsync() system call is broken.

 

综上,总结如下:

1)数据库多线程模下,有并发事务或并发事务多会超成数据库操作拥堵,这个与数据库模式无关(FMDB queue解决)

2)事务中有大数据(几千条)的先条件查询后更新或插入操作时会很慢(避免事务中大数据条件查询)

2)开启WAL模式;

3)区分对待数据库串行模式和串行数据库操作队列;

     目前,我采用的是:a)多线程数据库操作+FMDB Queue(W/R两队表两数据库连接)+数据库SQLITE_CONFIG_MULTITHREAD模式+WAL+事务中避免大数据条件查询

     但是,我觉得另一种方式的性能也应该不错:b)多线程数据库操作+数据库SQLITE_CONFIG_SERIALIZED模式+(WAL)+一个数据库连接+事务中避免大数据条件查询

 

     a)中数据库模式虽然是多线程(SQLITE_CONFIG_MULTITHREAD)模式,但所有程序级多线程数据库操作都被FMDB queue串行化,最多也就两个数据库并发(W/R),各自一个数据库连接; SQLITE_CONFIG_MULTITHREAD模式是好处在于读和写可分成各一个FMDB queue以及开启WAL模式支持可并发写和读

     b)中数据库模式是串行(SQLITE_CONFIG_SERIALIZED)模式且一个数据库连接,所以不需要队列来串行化程序级的多线程数据库操作;同时WAL模式是可选开启,如果开启则写数据库会更快,但没有并发的读和写(因为当前数据库是SQLITE_CONFIG_SERIALIZED模式)

1
0
分享到:
评论
6 楼 hibluse 2013-04-22  
handy.wang 写道
hibluse 写道
我已经设置了WAL模式。但是不起作用。就是上面我提到的问题。SQLITE_CONFIG_MULTITHREAD怎么设置,还需要设置吗?


你不用设置SQLITE_CONFIG_MULTITHREAD,因为FMDatabase默认的打开数据方法就是SQLITE_CONFIG_MULTITHREAD
方式;
如下:
- (BOOL)open {
    if (_db) {
        return YES;
    }
    sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
    int err = sqlite3_open((_databasePath ? [_databasePath fileSystemRepresentation] : ":memory:"), &_db );
    if(err != SQLITE_OK) {
        NSLog(@"error opening!: %d", err);
        return NO;
    }
    char *errorMsg = nil;
    if (sqlite3_exec(_db, "PRAGMA journal_mode=WAL;", NULL, NULL, &errorMsg) != SQLITE_OK) {
        NSLog(@"Failed to set WAL mode: %s",errorMsg);
    }
    sqlite3_wal_checkpoint(_db, NULL);
    return YES;
}

请问,sqlite支持多线程吗?我设置了 synchronous= normal 貌似可以用。我做了测试。但是我不确认是否真的多线程是支持的。能具体描述一下吗。谢谢
5 楼 handy.wang 2013-03-21  
hibluse 写道
请问,在java里这个SQLITE_CONFIG_MULTITHREAD怎么设置


这个我问过我做Android开发的同事,他们用得现成封装没有配置这个。
我正在请教我另一个做Android的同事,还没有回信。
4 楼 handy.wang 2013-03-21  
hibluse 写道
我已经设置了WAL模式。但是不起作用。就是上面我提到的问题。SQLITE_CONFIG_MULTITHREAD怎么设置,还需要设置吗?


你不用设置SQLITE_CONFIG_MULTITHREAD,因为FMDatabase默认的打开数据方法就是SQLITE_CONFIG_MULTITHREAD
方式;
如下:
- (BOOL)open {
    if (_db) {
        return YES;
    }
    sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
    int err = sqlite3_open((_databasePath ? [_databasePath fileSystemRepresentation] : ":memory:"), &_db );
    if(err != SQLITE_OK) {
        NSLog(@"error opening!: %d", err);
        return NO;
    }
    char *errorMsg = nil;
    if (sqlite3_exec(_db, "PRAGMA journal_mode=WAL;", NULL, NULL, &errorMsg) != SQLITE_OK) {
        NSLog(@"Failed to set WAL mode: %s",errorMsg);
    }
    sqlite3_wal_checkpoint(_db, NULL);
    return YES;
}
3 楼 handy.wang 2013-03-21  
hibluse 写道
我已经设置了WAL模式。但是不起作用。就是上面我提到的问题。SQLITE_CONFIG_MULTITHREAD怎么设置,还需要设置吗?



sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
2 楼 hibluse 2013-03-04  
我已经设置了WAL模式。但是不起作用。就是上面我提到的问题。SQLITE_CONFIG_MULTITHREAD怎么设置,还需要设置吗?
1 楼 hibluse 2013-03-04  
请问,在java里这个SQLITE_CONFIG_MULTITHREAD怎么设置

相关推荐

    IOS 20个实用例子.zip

    -- IOS sqlite数据库操作 -- IOS XMPP 聊天程序客户端 -- 使用Delegate在两个ViewController间传值 -- 内存泄露Demo leaky app -- iOS上拉加载更多的实现 -- iOS视频通话/直播demo -- 数据库操作(使用FMDB) -- iOS...

    ios-一款用 Segment 布局,FMBD为数据库,很简单的有各种英雄联盟视频浏览的新新手入门APP.zip

    2. **FMBD(可能是FMDB的误写)**:FMDB是一个Objective-C的SQLite数据库管理库,它是SQLite的轻量级封装,使得在iOS应用中操作数据库变得更为便捷。开发者可以利用FMDB进行数据的存储、查询、更新和删除操作。在...

    iOS App使用SQLite之句柄的定义及数据库的基本操作

    在iOS应用开发中,SQLite是一种常用的轻量级关系型数据库,用于存储和管理应用程序的数据。在SQLite中,"句柄"...通过熟练掌握句柄的使用,开发者可以更好地管理SQLite数据库,从而提升应用程序的性能和用户体验。

    IOS企业面试题整理

    - SQLite数据库操作,以及FMDB等第三方库的应用。 - UserDefaults的使用场景及其限制。 8. **安全与性能优化**: - App的安全实践,如HTTPS加密、防止SQL注入、权限管理等。 - 性能优化,包括内存优化、启动...

    ios导出数据至Excel

    - SQLite数据库:通过使用SQLite.swift或FMDB等第三方库,我们可以查询并获取SQLite数据库中的数据。 - Core Data:利用NSManagedObjectContext对象和NSFetchRequest,我们可以检索存储在Core Data中的信息。 - ...

    Professional iOS Database Application Programming源码

    源码可能包含了一些基准测试和性能分析的例子,帮助开发者理解如何在实际项目中优化数据库性能。 数据同步和备份也是重要的知识点,特别是对于需要云同步的应用。源码可能展示了如何使用iCloud或自定义服务实现数据...

    iOS - 记账

    1. **FMDB**:FMDB是Objective-C编写的SQLite数据库管理库,用于iOS应用的数据持久化。在这个记账APP中,FMDB被用来存储用户的交易记录、账户信息等数据。SQLite是一个轻量级的关系型数据库,支持事务处理,确保数据...

    HQPhotoLock:图片保险箱

    另外,代码中使用了作者自己写的基于FMDB的Sqlite数据库操作器: BaseDBMasterKey(已改名为), 非常简单就可以操作数据库!代码中用于加密的密钥已经修改过了, 和已发布的app中的不一致, 所以不会导致安全问题.独创的...

    设计一个移动应用的本地缓存机制

    在实际开发中,可以结合第三方库如SDWebImage处理图片缓存,FMDB处理SQLite数据库,或者Alamofire的缓存功能等,以简化开发流程。 总之,设计一个优秀的移动应用本地缓存机制需要综合考虑多种因素,既要保证数据的...

    ios-手势解锁Demo,持久化本地存储.zip

    FMDB是一个Objective-C的SQLite库,它提供了一套简单易用的API来操作SQLite数据库。在手势解锁的场景中,FMDB可以用来存储用户设置的手势路径信息。当用户创建新手势时,这些路径数据会被转换成可存储的形式(可能是...

    非常经典的开发面试专用

    - **FMDB**:简单易用的SQLite数据库封装库。 - **Masonry**:强大的Auto Layout辅助库。 - **友盟分享**、**百度地图**、**二维码扫描**等插件的集成与使用。 #### 八、iOS应用开发与发布流程 - **开发账号与证书...

    VVSequelize:数据库模型映射,自动建表, 自动更新表,数据增删改查, FTS全文搜索, 支持自定义fts3,4,5分词器,可拼音分词. sql,fmdb,wcdb,sqlite3,orm,fts,fts3,fts4,fts5

    不建议访问appgroup中的数据库, 所以去掉此功能. 移除cache. 因为sqlite3_update_hook()不能完全hook所有delete, drop操作, cache将不能被有效更新,会导致查询到错误数据, 所以去掉此功能, 由用户自行管理缓存. ...

    集成iOS开发中常用功能模块.zip

    另一个选择是使用SQLite.swift或FMDB库直接操作SQLite。HQYModules-master可能包含CoreData或SQLite的使用示例,帮助开发者学习如何存储和检索数据。 推送通知是增强用户体验的方式之一,iOS提供了本地通知和远程推...

    《30天精通iPhone手机编程》源码第二部分

    7. **SQLite或FMDB**:作为Core Data的补充,开发者可能学习使用SQLite数据库,或者通过FMDB库进行操作,实现更底层的数据存储。 8. **多线程**:了解并实践GCD(Grand Central Dispatch)、NSOperationQueue和...

    史上最全的ios开发源码

    基于FMDB的数据库操作 简单阅读器 键盘类 键盘(Keyboard)之自定义表情键盘 键盘-FaceBoard 键盘-Keyboard Bar TextField 键盘类》》Number PadView 键盘类》》ZenKeyboard 键盘类--自定义的拨号键盘 键盘之...

    面试题第4篇1

    FMDB(问题244)是iOS平台上一个流行的SQLite数据库管理库,它是Objective-C编写的,提供了一种简单的方式来操作SQLite数据库。在iOS应用中,你可以使用FMDB来执行SQL查询,插入、更新或删除数据。例如,如果你需要...

    IOS应用源码之colloquy-latest.zip

    Colloquy可能会使用FMDB这样的Objective-C SQLite库来操作数据库。 6. **推送通知**:为了让用户即使在应用关闭时也能收到新消息,Colloquy可能实现了Apple的Push Notification服务,这需要后端服务器与iOS设备进行...

    【圈里求职】通用简历 (2).docx

    - **互联派医疗质量查核系统**:基于SSH架构,使用Oracle数据库,负责护理部质量查核模块的开发,包括调查问卷和数据分析。 这些知识点充分体现了求职者的全面技术能力,涵盖从基础编程到高级应用,包括前端UI设计...

    ios学习文件

    6. **FMDB数据库操作示例**:FMDB是一个基于SQLite的封装库,简化了数据库操作的复杂性。本文档将通过具体示例介绍如何使用FMDB进行增删改查等基本操作。 7. **OpenGL ES图形渲染实践**:通过实际案例演示如何利用...

Global site tag (gtag.js) - Google Analytics