如何提高 SQLite 数据库的性能?
Posted
技术标签:
【中文标题】如何提高 SQLite 数据库的性能?【英文标题】:How can i improve the performance of the SQLite database? 【发布时间】:2011-04-26 11:45:30 【问题描述】:背景:我在我的 flex 应用程序中使用 SQLite 数据库。数据库大小为 4 MB,有 5 个表
-
表 1 有 2500 条记录
表2有8700条记录
表 3 有 3000 条记录
表 4 有 5000 条记录
表 5 有 2000 条记录。
问题:每当我对任何表运行选择查询时,从数据库表中获取数据大约需要(大约 50 秒)。这使得应用程序在从表中获取数据时非常缓慢且无响应。
如何提高 SQLite 数据库的性能,从而减少从表中获取数据所需的时间?
谢谢
【问题讨论】:
也许您可以告诉我们表有哪些结构以及您对它们运行的哪些查询?答案可能是:“使用索引”,或“重新处理查询”。另请注意,SQLite 用一个 L 和三个前导大写字母拼写。 【参考方案1】:正如我在评论中告诉您的那样,在不知道您的数据库由什么结构组成以及您对数据运行什么查询的情况下,我们无法推断出您的查询为何需要很多时间。
然而,这里有一篇关于索引的有趣读物:Use the index, Luke!。它会告诉您什么是索引、应该如何设计索引以及可以获得哪些好处。
此外,如果您可以发布查询、表架构和基数(不是内容),也许会有所帮助。
【讨论】:
【参考方案2】:您使用的是异步还是同步执行模式?它们之间的区别在于异步执行在后台运行,而您的应用程序继续运行。然后,您的应用程序将必须侦听已调度的事件,然后执行任何后续操作。然而,在同步模式下,用户将无法与应用程序交互,直到数据库操作完成,因为这些操作以与应用程序相同的执行顺序运行。同步模式在概念上实现起来更简单,但异步模式会产生更好的可用性。
SQLStatement.execute()
第一次在 SQLStatement
实例上,语句在执行前自动准备。只要SQLStatement.text
属性未更改,后续调用将执行得更快。使用相同的SQLStatement
实例比一次又一次地创建新实例要好。如果您需要更改查询,请考虑using parameterized statements。
您还可以使用诸如在运行时延迟所需数据等技术。如果您只需要一部分数据,请先将其拉回,然后根据需要检索其他数据。这可能取决于您的应用范围以及您必须满足的需求。
如果您有多个数据库,使用表名指定数据库将阻止运行时检查每个数据库以找到匹配的表。如果未指定,它还有助于防止运行时选择错误的数据库。即使您只有一个数据库,也要使用 SELECT email FROM main.users;
而不是 SELECT email FROM users;
。 (当您调用SQLConnection.open
时,main
会自动分配为数据库名称。)
如果您碰巧要对数据库进行大量更改(多个INSERT
或UPDATE
语句),那么请考虑将其包装在事务中。运行时将在内存中进行更改,然后写入磁盘。如果不使用事务,每条语句都会导致多次磁盘写入数据库文件,这可能会很慢并且会耗费大量时间。
尽量避免任何架构更改。表定义数据保存在数据库文件的开头。运行时在打开数据库连接时加载这些定义。添加到表中的数据保留在数据库文件中的表定义数据之后。如果发生更改,例如添加列或表,新的表定义将与数据库文件中的表数据混合在一起。这样做的效果是运行时将不得不从文件的不同部分而不是在开始时读取表定义数据。 SQLConnection.compact()
方法对表定义数据进行了重组,使其位于文件的开头,但它的缺点是如果数据库文件很大,这种方法也会消耗很多时间。
最后,正如Benoit 在他的评论中指出的那样,考虑改进您自己的 SQL 查询和您正在使用的表结构。了解您的数据库结构和查询是否是性能缓慢的实际原因会很有帮助。我的猜测是您正在使用同步执行。如果切换到异步模式,您会看到更好的性能,但这并不意味着它必须停在那里。
Adobe Flex 在线文档有更多关于improving database performance 和best practices working with local SQL databases 的信息。
【讨论】:
【参考方案3】:您可以尝试为 SELECT 语句的 WHERE 子句中使用的某些列建立索引。您也可以尝试尽量减少 LIKE 关键字的使用。
如果您要将表连接在一起,您可以尝试简化表关系。
正如其他人所说,如果不了解您的架构和您正在使用的 SQL 的更多信息,就很难具体说明。
【讨论】:
以上是关于如何提高 SQLite 数据库的性能?的主要内容,如果未能解决你的问题,请参考以下文章