【问题标题】:Performance of queries using count(*) on tables with many rows (300 million+)在多行(超过 3 亿行)的表上使用 count(*) 的查询性能
【发布时间】:2012-02-13 08:37:38
【问题描述】:

我知道使用 sqlite 有一些限制,但我想知道它是否应该能够处理这种情况。

我的表有超过 3 亿条记录,数据库大约 12 个演出。使用 sqlite 的数据导入工具既好又快。但是后来我给这个表的一个字符串列添加了索引,它跑了一夜才完成这个操作。我没有将此与其他数据库进行比较,但对我来说似乎很慢。

现在我的索引已添加,我想在数据中查找重复项。所以我正在尝试运行“计数> 0”查询,它似乎也需要几个小时。我的查询看起来像:

select col1, count(*) 
from table1
group by col1
having count(*) > 1

我会假设这个查询会使用我在 col1 上的索引,但是缓慢的查询执行让我想知道它是否不是?

也许 sql server 会更好地处理这种事情吗?

【问题讨论】:

  • 您是否尝试检查explain plan 以查看是否使用了索引?无论如何,12 GIG 只是数据,索引应该是额外的几个 GIG。我认为与其他替代方案相比,SQLite 的表现可能太过分了,尽管理论上 limit 是 140 TERA。
  • 其实我忘了说,索引后文件大小基本上翻了一番——12gb到24gb
  • 我会运行解释看看,谢谢

标签: sql sql-server performance sqlite


【解决方案1】:

SQLite 的 count() 未优化 - 即使已编入索引,它也会执行全表扫描。这是recommended approach to speed things up。运行EXPLAIN QUERY PLAN进行验证,你会看到:

EXPLAIN QUERY PLAN SELECT COUNT(FIELD_NAME) FROM TABLE_NAME;

我得到这样的东西:

0|0|0|SCAN TABLE TABLE_NAME (~1000000 rows)

【讨论】:

  • 实际上,这仍然无法解释 - 具有 count(*) > 1 意味着它应该只对匹配的子集进行计数,该子集被索引......所以我认为它不会扫描整个表的每一行?
  • 我知道您的表很大,但是您是否在查询中运行了EXPLAIN QUERY PLAN?我创建了一个包含两列INTEGER PRIMARY KEYTEXT 的测试表(SQLite 3.7.7)(文本字段col1 上的索引)。但是结果是0|0|0|SCAN TABLE TEST_TABLE_NAME USING COVERING INDEX data_values (~1000000 rows),表示索引没有被使用。
【解决方案2】:

但后来我在这个表中的一个字符串列中添加了一个索引,它运行了一整夜来完成这个 手术。我没有将它与其他数据库进行比较,但对我来说似乎很慢。

我不想告诉你,但是你的服务器看起来怎么样?不争辩,但这可能是一个非常耗费资源的操作,可能需要大量的 IO 和普通计算机或具有慢速硬盘的 chehap Web 服务器不适合重要的数据库工作。我运行数百 og 千兆字节的数据库项目工作,我最小的“大数据”服务器有 2 个 SSD 和 8 个 Velociraptors 用于数据和日志。最大的一个有 3 个存储节点,总共有 1000gb SSD 磁盘 - 仅仅是因为 IO 是数据库服务器赖以生存和呼吸的东西。

所以我正在尝试运行“计数 > 0”查询,它似乎也需要几个小时

多少内存?足以将其全部放入内存中,还是内存不足的虚拟服务器中缺少的内存会导致错误的 IO? SqlLite 可以/可以使用多少内存?温度设置如何?在记忆中? Sql server 可能会使用大量内存/tempdb 空间进行此类检查。

【讨论】:

  • 我看到的内存并没有填满(我有 8 个演出),而且它似乎也没有做太多的 io。它似乎只是消耗处理器......这很奇怪。
  • 完全没有。您计划仅使用一个内核以慢速语言进行大量操作。你期待什么?
  • 四核,但这有关系吗?但我真正的问题是——我从来没有见过其他数据库性能如此糟糕,从历史上看,当我使用索引时,无论数据集有多大,一切都很开心。这似乎有些事情不正常,或者 sqlite 太轻量级了。
  • 我使用的语言是... SQL。 sqlite 哪个更快?
【解决方案3】:

通过PRAGMA cache_size=<number of pages>增加sqlite缓存。使用的内存是<number of pages> 乘以<size of page>。 (可以通过PRAGMA page_size=<size of page>设置)

通过将这些值分别设置为 16000 和 32768(或大约 512MB),我能够将这个程序的批量加载从 20 分钟缩短到 2 分钟。 (虽然我认为如果该系统上的磁盘不是那么慢,这可能不会产生太大的影响)

但是在较小的嵌入式平台上您可能没有这些额外的内存可用,我不建议像在那些平台上那样增加它,但对于台式机或笔记本电脑级别的系统,它可以提供很大帮助。

【讨论】:

  • 批量加载足够快,现在是索引和重复数据删除查询问题
猜你喜欢
  • 2019-04-17
  • 2013-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-10
  • 2020-08-04
  • 2012-11-30
相关资源
最近更新 更多