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

其中一张表相当大(800 万行以上,大约 30 列)。表的大小显然会影响通过存储过程从表中选择项目的网站的性能。该表已建立索引,但由于表中的行数过多,性能仍然很差 - 这是问题的一部分 - 该表的读取和更新一样,因此我们无法在不执行以下操作之一的情况下添加/删除索引运营情况更差。

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

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

有帮助吗?

解决方案

您始终可以推出自己的“穷人分区/DPV”,即使它听起来不像正确的方法。这只是一个广泛的概念方法:

  1. 为当年的数据创建一个新表 - 相同的结构,相同的索引。调整写入主大表的存储过程以写入两个表(只是暂时的)。我建议使存储过程中的逻辑为 IF CURRENT_TIMESTAMP >= '[some full date without time]' - 这将使回填此表中的数据变得容易,该数据预先记录了开始记录的过程的更改。

  2. 使用主表中的 SELECT INTO 为历史记录中的每一年创建一个新表。您可以在同一实例的不同数据库中执行此操作,以避免当前数据库的开销。我认为历史数据不会改变,因此在另一个数据库中,您甚至可以将其设置为仅在完成时才读取(这将显着提高读取性能)。

  3. 一旦您拥有整个表的副本,您就可以创建仅引用当前年份的视图,另一个引用 2005 年到当前年份的视图(通过在当前表和其他数据库中 >= 2005 年的表之间使用 UNION ALL ),另一个引用所有三组表格(提到的表格以及 2005 年之前的表格)。当然,你可以进一步分解它,但我只是想让这个概念最小化。

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

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

我不了解您情况的所有详细信息,但如果您有疑问或疑虑,请跟进。我已经在几个迁移项目中使用了这种方法,其中包括目前正在进行的一个项目。

其他提示

  

性能差由于行的表中的绝对数量

800万行不健全所有的疯狂。你检查你的查询计划?

  

表作为同样读作更新

您实际更新索引列,或者它同样读取和插入的到?

  

(没有,在其掷硬件是不会发生任一)

这是一个遗憾,因为RAM是便宜。

重建所有索引。这将提高查询的性能。如何做到这一点是 以及更多关于聚集和非聚集索引重建的影响 这里

其次,对存储数据库的驱动器执行碎片整理。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top