在SQLite 3下优化select with transaction

Ste*_*tef 20 sqlite transactions query-optimization

我读了包裹了很多SELECTBEGIN TRANSACTION/COMMIT是一个有趣的优化.

但是,如果我PRAGMA journal_mode = OFF之前使用" ",这些命令真的是必要的吗?(如果我记得的话,禁用日志,显然也禁用交易系统.)

ele*_*ice 22

请注意,我不同意BigMacAttack.

对于SQLITE,在事务包装SELECT 做一些事情:它减少了获取然后删除的SHARED锁的数量.

参考:http: //www.mail-archive.com/sqlite-users%40sqlite.org/msg79839.html

所以我认为即使你关闭了journal_mode,事务也会有好处,因为仍然需要考虑锁定开销.

也许read_uncommitted是你可以考虑的东西 - 我猜它会禁用SHARED锁定.


Big*_*ack 14

"使用交易 - 即使您只是在阅读数据.这可能会产生几毫秒."

我不确定Katashrophos.net博客在哪里获取这些信息,但SELECT在事务中包装语句什么都不做.事务始终只在更改数据库时使用,并且无法禁用事务.他们是一个要求.许多人不理解的是,除非你手动BEGINCOMMIT一个事务,否则每个语句都会自动放入自己独特的事务中.一定要阅读关于提高sqlite性能的事实上的SO问题.博客作者可能试图说的是,如果你打算做一个INSERT,然后是a SELECT,那么另一个INSERT,然后它会提高性能,以便在单个事务中手动包装这些语句.否则sqlite会自动将两个insert语句放在单独的唯一事务中.

根据"关于事务的SQL语法"文档:
"除了事务之外,不能对数据库进行任何更改.任何更改数据库的命令(基本上,除了之外的任何SQL命令SELECT)都会自动启动事务,如果有的话尚未生效."

最后,禁用日记PRAGMA journal_mode = OFF功能不会禁用事务,只会记录日志.但禁用日志也是提高性能的好方法.通常在每次交易之后,sqlite都会记录日记中的交易.如果不必这样做,您将获得性能提升.

更新:
因此,"优雅骰子"引起了我的注意,我上面引用的SQLite文档声明具有误导性.SELECT语句确实使用事务系统.这用于获取和释放SHARED数据库上的锁.因此,SELECT在单个事务中包装多个语句确实更有效.通过这样做,锁只被获取和释放一次,而不是每个单独的SELECT声明.这最终会稍微提高效率,同时还要确保所有SELECT语句都能访问相同版本的数据库,以防某些其他程序添加/删除某些内容.

  • 我完全不同意这个答案.每个SELECT都在一个事务中,无论你是否手动BEGIN/END.因此,如果要执行多个SELECT语句,则应将它们包装在BEGIN/END事务中.如果你做包装,则有1个事务,2个选择.如果你不换行,则有2个交易,2个选择. (7认同)
  • 我跟进了,并且可以确认你应该在事务中包装多个选择,以获得性能,因为每个SELECT都获得然后丢弃一个SHARED锁.在事务中包装所有内容可以减少锁定开销. (5认同)
  • 嗯,你是对的,我的坏,我误读了这个:https://sqlite.org/lang_transaction.html ...但是如果你想要"一致读取"(即多个SELECTS都给出相同的结果),那么你需要包裹在BEGIN/END中.但是,如果您正在进行一次性SELECT,或者不关心一致性,那么您根本不需要事务.我想知道如何在没有事务开销的情况下在sqlite中创建一个SHARE-ONLY锁? (3认同)