【问题标题】:How to deal with billions of records in an sql server?如何处理 sql server 中的数十亿条记录?
【发布时间】:2011-06-23 23:54:34
【问题描述】:

我有一个 sql server 2008 数据库,其中一个主要表中有 30000000000 条记录。现在我们正在寻找查询的性能。我们已经完成了所有索引。我发现我们可以将我们的数据库表拆分为多个分区,这样数据就会分布在多个文件中,这会提高查询的性能。

但是很遗憾,这个功能只有在 sql server 企业版中才有,我们买不起。

有没有办法优化查询性能?例如查询

select * from mymajortable where date between '2000/10/10' and '2010/10/10'

检索大约 10000 条记录大约需要 15 分钟。

【问题讨论】:

  • 您始终可以将数据库拆分为多个分区。你不必买任何东西。您只需要自己查询正确的表,而不是服务器找出哪个表。
  • 另外,如果一个 10 年的日期范围仅包含 10,000 条记录,那么其他 29,999,990,000 条记录的范围是什么?这种情况完全是虚构/假设的吗?我看到你已经对 Mitch 的帖子发表了评论说你没有使用 * 你还漏掉了什么?
  • 不要只在字段上创建索引,而是在字段组合上创建索引,并使用包含的列来存储您经常检索的数据。
  • 升级到企业版。正确地做。

标签: sql-server


【解决方案1】:

显然,SELECT * 的服务效率低于使用覆盖索引的查询。

第一步:检查查询计划并查找和表扫描以及最费力的步骤(%)

如果您的“日期”列上还没有索引,那么您当然需要一个(假设有足够的选择性)。尝试减少选择列表中的列,如果“足够”少,将这些添加到索引中作为included columns(这可以消除对聚集索引的书签查找并提高性能)。

您可以将数据分解为单独的表格(例如按日期范围)并通过视图进行组合。

它还非常依赖于您的硬件(# 个内核、RAM、I/O 子系统速度、网络带宽)

建议您发布您的表和索引定义。

【讨论】:

  • 谢谢。我正在避免 * 功能,这只是示例。您还有其他可以提高性能的想法吗?
【解决方案2】:

我们讨论的是什么类型的查询?

这是生产表吗?如果是,请进一步规范化,看看您是否不能更进一步规范化数据库。

如果这是用于报告,包括大量 Ad Hoc 报告查询,那么数据仓库会尖叫。

我会创建一个带有单独的预处理报告的 DW,其中包括您可能期望的所有计算和聚合。

我有点担心涉及处理大数据但没有产生足够收入甚至吸引足够风险投资升级到企业的商业模式。

【讨论】:

    【解决方案3】:

    您可能会考虑创建一个存档数据库,并在 10 到 20 年后将任何东西移入存档数据库。这应该会大大加快您的主要生产数据库的速度,但会保留所有历史数据以满足报告需求。

    【讨论】:

      【解决方案4】:

      首先始终避免使用Select *,因为这会导致选择获取所有列,并且如果存在仅包含您需要的列的索引,则您将获取大量不必要的数据。仅使用您需要检索的确切列可以让服务器更好地利用索引。

      其次,查看索引的包含列,这样可以将经常请求的数据包含在索引中,以避免获取行。

      第三,您可以尝试使用 int 列作为日期并将日期转换为 int。在范围搜索中,整数通常比日期更有效,特别是如果您有时间信息,并且如果您可以跳过时间信息,则索引会更小。

      要检查的另一件事是服务器使用的执行计划,如果您在菜单中启用显示执行计划,您可以在管理工作室中看到这一点。它可以指出问题所在,您可以查看它尝试使用的索引,有时它会建议添加新索引。

      它也可以表示其他问题,Table Scan 或 Index Scan 不好,因为它表明它必须扫描整个表或索引,而 index seek 是好的。

      这是了解服务器工作原理的好来源。

      【讨论】:

        【解决方案5】:

        如果您在日期添加索引,由于索引搜索 + 键查找而不是聚集索引扫描,您可能会加快查询速度,但如果您的日期过滤器将返回太多记录,则索引将无济于事完全是因为对索引查找的每个结果都执行了键查找。 SQL 服务器随后将切换到聚集索引扫描。

        要获得最佳性能,您需要创建一个覆盖索引,即在索引的“包含的列”部分中包含您需要的所有列,但如果您使用 select * 则这对您没有帮助

        select * 方法的另一个问题是您不能以有效的方式使用缓存或执行计划。如果您确实需要所有列,请确保指定所有列而不是 *。

        您还应该完全限定对象名称以确保您的计划是可重复使用的

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-22
          • 1970-01-01
          • 2019-04-22
          • 2013-11-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多