代码之家  ›  专栏  ›  技术社区  ›  Scott

SQL 2005数据库中的大表需要更好的性能!

  •  0
  • Scott  · 技术社区  · 15 年前

    我正在开发一个使用SQL 2005(标准版)数据库的数据驱动Web应用程序。

    其中一个表相当大(800多万行,大约有30列)。表的大小对通过存储过程从表中选择项目的网站的性能有明显的影响。该表已编入索引,但由于表中的行太多,性能仍然很差-这是问题的一部分-该表的读取与更新相同,因此我们无法在不使某个操作变得更糟的情况下添加/删除索引。

    我在这里的目标是在从表中选择项时提高性能。该表包含“当前”数据和旧的/几乎未触及的数据。在这个阶段,我们能想到的最有效的解决方案是将表格分为2个部分,即一个用于旧项目(在某个日期之前,例如2005年1月1日),另一个用于新项目(等于或在2005年1月1日之前)。

    我们知道分布式分区视图之类的东西——但是所有这些功能都需要企业版,而客户机不会购买企业版(不,向企业版扔硬件也不会发生)。

    3 回复  |  直到 14 年前
        1
  •  3
  •   Aaron Bertrand    15 年前

    你可以随时滚动你自己的“可怜人的分区/DPV”,即使它闻起来不是正确的方法。这只是一个广泛的概念方法:

    1. 为当前年份的数据创建一个新表-相同的结构,相同的索引。调整写入主表和大表的存储过程,以便同时写入两个表(只是暂时的)。我建议将存储过程中的逻辑设为if current_timestamp>='[某个没有时间的完整日期]”-这样可以很容易地将此表中的数据进行回填,从而提前将更改记录到该表中的过程的日期。

    2. 使用主表中的select into为历史记录中的每一年创建一个新表。您可以在同一实例的不同数据库中执行此操作,以避免当前数据库中的开销。我想历史数据不会改变,所以在另一个数据库中,您甚至可以在完成后使其只读(这将显著提高读取性能)。

    3. 一旦您拥有了整个表的副本,就可以创建仅引用当前年份的视图、引用2005年的当前年份的另一个视图(通过在当前表和其他数据库中的>=2005数据库中使用union all),以及引用所有三组表的另一个视图(所提到的表以及-日期2005)。当然,你可以更进一步地打破这一点,但我只是想让这个概念保持最小。

    4. 将读取数据的存储过程更改为“更智能”-如果请求的日期范围在当前日历年内,请使用仅在本地的最小视图;如果日期范围为>=2005,则使用第二个视图,否则使用第三个视图。如果您所做的不仅仅是插入仅与当前年份相关的新数据,那么您可以对写入的存储过程遵循类似的逻辑。

    5. 此时,您应该能够停止插入到大容量表中,并且,一旦证明一切正常工作,就将其丢弃并回收一些磁盘空间(我的意思是释放数据文件中的空间以供重用,而不是执行收缩数据库,因为您将再次使用该空间)。

    我不知道你情况的所有细节,但如果你有问题或疑虑,请跟进。我在几个迁移项目中使用了这种方法,包括目前正在进行的一个项目。

        2
  •  1
  •   Jonas Elfström    15 年前

    由于表中的行太多,性能很差

    800万行听起来并不那么疯狂。你查过你的查询计划了吗?

    表的读取与更新相同

    您实际上是在更新索引列还是同样地读取它,并且 插入的 去?

    (不,扔硬件也不会发生)

    真可惜,公羊太便宜了。

        3
  •  1
  •   Dori Nimit Parekh    14 年前

    重新生成所有索引。这将提高查询的性能。 如何做到这一点 this 对聚集索引和非聚集索引重建的影响 here

    其次,在存储数据库的驱动器上执行碎片消除。