0

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

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

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

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

4

3 回答 3

3

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

  1. 为当年的数据创建一个新表 - 相同的结构,相同的索引。调整写入主大表的存储过程以写入两个表(只是暂时的)。我建议将存储过程中的逻辑设置为 IF CURRENT_TIMESTAMP >= '[some whole date without time]' - 这样可以轻松回填此表中的数据,该数据早于对开始记录的过程进行更改的日期。

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

  3. 获得整个表的副本后,您可以创建仅引用当前年份的视图,另一个将 2005 年引用到当前年份的视图(通过在当前表和其他数据库中 >= 2005 的表之间使用 UNION ALL ),另一个引用所有三组表(提到的那些,以及 2005 年之前的表)。当然,您可以将其分解得更多,但我只是想保持概念最小化。

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

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

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

于 2010-02-08T06:48:31.203 回答
1

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

其次,在存储 DB 的驱动器上执行碎片整理。

于 2010-02-08T08:09:54.957 回答
1

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

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

该表的阅读与更新相同

您实际上是在更新索引列还是同样读取和插入它?

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

很遗憾,因为 RAM 非常便宜。

于 2010-02-08T13:57:41.053 回答