我正在开发一个使用SQL 2005(标准版)数据库的数据驱动Web应用程序。
其中一个表格相当大(800万+行大,约30列)。表的大小显然影响网站的性能,该网站通过存储过程从表中选择项目。该表已编制索引,但由于表中的行数量很大,性能仍然很差 - 这是问题的一部分 - 表与更新的读取一样,因此我们无法添加/删除索引操作更糟。
我在这里的目标是在从表格中选择项目时提高性能。该表包含“当前”数据和旧/几乎未触及的数据。我们在这个阶段可以想到的最有效的解决方案是将表分成2个,即一个用于旧项目(在某个日期之前,比如说2005年1月1日)和一个用于新项目(等于或等于2005年1月1日)
我们知道像分布式分区视图这样的东西 - 但所有这些功能都需要企业版,客户端不会购买(并且不会抛出硬件也不会发生)。
答案 0 :(得分:3)
你总是可以推出自己的“穷人的分区/ DPV”,即使它没有像正确的方式一样。这只是一个广泛的概念方法:
为当前年份的数据创建一个新表 - 相同的结构,相同的索引。调整写入主,大表的存储过程以写入两个表(只是暂时)。我建议在存储过程中使逻辑说IF CURRENT_TIMESTAMP> ='[没有时间的整个日期]' - 这样可以很容易地回填此表中的数据,该数据在更改为开始在那里开始记录的过程之前更新。
使用主表格中的SELECT INTO为历史记录中的每一年创建一个新表格。您可以在同一实例上的不同数据库中执行此操作,以避免当前数据库中的开销。我认为历史数据不会改变,因此在这个其他数据库中,您甚至可以在完成后将其读取(这将显着提高读取性能)。
获得整个表的副本后,您可以创建仅引用当前年份的视图,另一个引用2005年当前年份的视图(通过在当前表和其他表之间使用UNION ALL)数据库是> = 2005),另一个引用所有三组表(提到的那些表和2005年之前的表)。当然,你可以更多地解决这个问题,但我只是想把概念保持在最低限度。
将读取数据的存储过程更改为“更智能” - 如果请求的日期范围在当前日历年内,请使用仅本地的最小视图;如果日期范围是> = 2005,则使用第二个视图,否则使用第三个视图。如果您只是插入仅与当前年份相关的新数据,则可以使用与写入的存储过程类似的逻辑。
此时你应该能够停止插入海量表了,一旦所有东西都被证明有效,就放下它并回收一些磁盘空间(我的意思是释放数据文件中的空间) (s)重用,不执行缩减数据库 - 因为您将再次使用该空间。)
我没有您所有情况的详细信息,但如果您有任何问题或疑虑,请跟进。我在几个迁移项目中使用了这种方法,包括现在正在进行的一个。
答案 1 :(得分:1)
答案 2 :(得分:1)
由于表格中存在大量的行,性能很差
800万行听起来并不那么疯狂。您检查了查询计划吗?
该表与更新
同样重要
您实际上是在更新索引列还是同等读取并插入?
(不,也不会向它投掷硬件)
这很可惜因为RAM很便宜。