【问题标题】:Sqlite slow but barely using machine ressourcesSqlite 缓慢但几乎不使用机器资源
【发布时间】:2014-06-01 12:39:11
【问题描述】:

我有一个大约 500 万行的 500MB sqlite 数据库,其架构如下:

CREATE TABLE my_table (
        id1 VARCHAR(12) NOT NULL,
        id2 VARCHAR(3) NOT NULL,
        date DATE NOT NULL,
        val1 NUMERIC,
        val2 NUMERIC,
        val2 NUMERIC,
        val4 NUMERIC,
        val5 INTEGER,
        PRIMARY KEY (id1, id2, date)
);

我正在尝试运行:

SELECT count(ROWID) FROM my_table

查询现在已经运行了几分钟,这对我来说似乎太过分了。我知道 sqlite 没有针对 count(*) 类型的查询进行优化。

如果至少我的机器看起来很努力,我可以接受这一点。但是,我的 CPU 负载徘徊在 0-1% 左右。 Process Explorer 中的“Disk Delta Total Bytes”约为 500.000。

知道这是否可以加快速度吗?

【问题讨论】:

  • 什么操作系统?什么文件系统?任何病毒扫描程序?
  • SQLite 不支持并发访问。一旦事务开始,它就会锁定表。您确定没有其他进程在同一个数据库的事务中闲置吗?
  • @CL Windows Server 2003 R2,赛门铁克端点保护
  • @aruisdante 这不意味着查询永远不会完成吗?就我而言,它确实如此,但速度很慢。
  • 什么文件系统?这是在网络上吗?

标签: sqlite


【解决方案1】:

您应该为您查询的任何字段建立一个索引,就像这样。 create index tags_index on tags(tag);。然后,我确信查询肯定会更快。其次,尝试规范化您的表格并进行测试(没有索引)。比较结果。

【讨论】:

  • 我的主键有什么问题?这已经是一个索引。据我所知,这张桌子在 3NF 中。
  • “索引无处不在”策略并没有加速一切,我怀疑没有 where 子句的计数可以在这样的表上加速。
【解决方案2】:

在大多数情况下,count(*) 会比 count(rowid) 快。

如果您有(非部分)索引,则可以更快地计算行数,因为需要从磁盘加载的数据更少。 在这种情况下,主键约束已经创建了这样一个索引。

【讨论】:

  • count(*) 有同样的问题:机器资源使用率低。我的理解是否正确,您是说我的主键架构原则上是可以的?
【解决方案3】:

如果我是你,我会尝试查看我的磁盘 IO。我想他们是相当高的。考虑到数据库的大小,一些数据必须在磁盘上,这使其成为瓶颈。

我对 SQLite 的基本知识的两个想法。

想法 1:如果在您的情况下内存不是问题并且您的应用程序启动一次并运行多个查询,我会尝试增加使用的缓存量(有一个 cache_size 可用的编译指示)。经过几次谷歌搜索后,我发现了这个关于 SQLite 调整的链接:http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html

想法 2:我会尝试使用自动递增的主键(在单个列上)并尝试使用 SELECT COUNT(DISTINCT row_id) FROM my_table; 调整我的请求。这可能会强制仅对索引中包含的内容进行计数。

【讨论】:

  • 我有 0.5MB/s 的磁盘 IO,这不是微不足道的,但留下了很大的空间......系统重新启动后,我现在的磁盘 IO 为 3-4 MB/s:这要好得多,但仍然.不知道是什么导致了这种速度的加快,也不知道为什么我以 3-4 MB/s 的速度达到顶峰。我将尝试您的想法,但我认为必须重新启动系统以避免系统缓存伪造结果。
猜你喜欢
  • 2011-12-26
  • 2013-12-14
  • 2022-12-04
  • 2012-03-04
  • 2018-04-16
  • 2022-08-24
  • 1970-01-01
  • 2011-05-20
  • 2023-01-17
相关资源
最近更新 更多