处理大型数据库
我已经在一个Web项目(asp.net)中工作了大约六个月。最终产品即将上线。该项目使用SQL Server作为数据库。我们已经对大量数据进行了性能测试,结果表明,当数据过大(例如200万行)(超时问题,响应延迟等)时,性能会下降。最初,我们使用的是完全规范化的数据库,但是由于性能问题(减少连接),现在我们对其进行了部分规范化。首先,这是正确的决定吗?
另外,当数据量很大时,可能的解决方案是什么。的客户将来会增加吗?
我想补充一点:
- 200万行是实体表,解决关系的表具有大得多的行。
- 数据+编号时,性能会下降。的用户增加。
- 在确定频繁使用的查询之后,进行了非规范化。
- 我们还使用了大量的xml列和xquery。这可能是原因吗?
- 我的项目中有些人说这个话题有些离题,他们说动态sql查询比存储过程方法要快。他们已经进行了某种性能测试以证明自己的观点。我认为情况恰恰相反。动态创建一些频繁使用的查询,其中大多数其他查询都封装在存储过程中。
解决方案
200万行通常不是非常大的数据库,具体取决于我们存储的信息类型。通常,当性能下降时,我们应该验证索引策略。 SQL Server数据库引擎优化顾问可能对我们有帮助。
At first we were using fully normailized database, but now we made it partially normailzed due to performance issues (to reduce joins).
俗话说:"归一化直到痛苦,反归一化直到起作用"。
在大型的,大量使用的数据库中,通常会看到一定程度的非规范化以提高性能,因此,只要性能仍在我们想要的位置并且代码可以管理,我现在就不用担心太多"非规范化"字段不会变得太繁琐。
what are the possible solutions when data size becomes very large, as the no. of clients increase in future?
由于对应用程序的域了解不多,很难说出如何对它进行过时的验证,但是如果流量大的数据库中有95%的用户正在查询,则将最近使用的数据和旧数据拆分为单独的表是一个相当普遍的方法他们最近30/45天的数据,拥有一个" live_data"表,该表包含例如最近60天的数据,以及一个" old_data"表(用于较旧的数据)可以提高性能。
一个好主意是确保我们设置了广泛的性能监视,以便可以在数据和负载增加时测量数据库的性能。如果发现性能明显下降,则可能是时候重新访问索引了!
那可能不是正确的决定。确定所有数据库交互并分别进行概要分析,然后找出有问题的交互并制定策略以最大程度地提高性能。另外,在数据库上打开审核日志并进行挖掘可能会提供更好的优化点。
可能有上百万个原因;使用SQL事件探查器和查询分析器来确定为什么查询会变慢,然后再进行"模式更改"。我们要做的并非全部都是创建几个索引并安排"更新统计信息"…………但正如我所说,探查器和查询分析器是找出正在发生的事情的最佳工具。 。
从事物的角度来看,几百万行并不是一个特别大的数据库。
假设我们正在谈论OLTP数据库,那么在不首先确定瓶颈的根本原因的情况下进行非规范化是一个非常非常糟糕的主意。
我们需要做的第一件事是在一个有代表性的时间段内分析查询工作负载,以识别大部分工作在哪里完成(例如,如果使用的是SQL Server,则使用SQL Profiler)。查看查询执行的逻辑读取数乘以执行次数。一旦确定了表现最差的十大查询,就需要详细检查查询执行计划。
我将在这里走出去(因为通常是这种情况),但是如果问题不是
- 缺少昂贵查询的"正确"覆盖索引
- 配置不佳或者在指定的磁盘子系统下
这样的答案描述了如何进行分析以查找工作负载中性能最差的查询。
As the old saying goes "normalize till it hurts, denormalise till it works".
我喜欢这个!这通常是一种必须不再接受的东西。我可以想象,回到DBASEIII时,一次不能打开4个以上的表(除非更改一些AUTOEXEC.BAT参数并重新启动计算机,啊哈!),这引起了人们的兴趣。在非规范化。
但是如今,我看到这种解决方案类似于园丁在等待海啸给草坪浇水的方法。请使用可用的喷壶(SQL事件探查器)。
并且不要忘记,每次对数据库的一部分进行非规范化时,随着代码错误风险的增加,使整个系统的可持续性越来越弱,我们进一步适应数据库的能力就会降低。
我们一直试图使用尽可能接近"现实世界"的数据库进行开发。这样一来,我们就避免了很多类似的陷阱,因为如果任何开发人员在调试过程中连接持续超时,他们都会下定决心。 Mitch Wheat建议的是调试IMO性能的最佳方法。配置文件以查找有问题的脚本并从中开始。优化脚本可能会使我们走得更远,然后需要查看索引。还要确保Sql Server具有足够的功能,尤其是IO(磁盘)很重要。并且不要忘记;缓存为王。内存便宜;买多点。 :)
首先,正如许多其他人所说,几百万行并不大。
我正在处理的当前应用程序有几个表,这些表都具有超过一亿行的行,这些行都已规范化。
我们确实遭受了一些糟糕的性能困扰,但这是由于使用默认表统计信息设置引起的。相对于表的总大小插入少量记录,即将一百万条记录插入包含100+百万条记录的表中并不会导致表统计信息的自动更新,因此我们会得到较差的查询计划,这些查询计划表现出来作为产生的串行查询而不是并行查询。
至于是否要进行非规范化是正确的决定,则取决于架构。我们是否需要定期执行深度查询,即是否需要执行大量连接才能获取我们经常需要访问的数据,如果这样,则部分去规范化可能是一种解决方法。
但是,在检查索引和表统计策略之前,请注意。
检查我们使用的是明智的,结构合理的查询,并且联接是否格式正确。检查查询计划,以确保查询实际上正在按照我们期望的方式进行解析。
正如其他人所说的那样,SQL Profiler /数据库引擎优化顾问确实可以很好地完成它。
对我来说,非规范化通常位于我要做的事情的最底部。
如果仍然有问题,请检查服务器软件和硬件设置。
- 数据库和日志文件是否使用单独的控制器存储在单独的物理磁盘上?
- 它有足够的内存吗?
- 日志文件是否设置为自动增长?如果是这样,则自动增长限制会降低到较低水平,即是否会增长到经常水平。
我们做任何工作都是正确的。
...只要我们意识到以后可能要付出代价。听起来我们无论如何都在考虑这个问题。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
检查事项:
死锁
- 所有进程是否都以相同顺序访问表?
缓慢
- 检查索引
请参阅我的其他有关一般效果提示的文章:
- 我们如何针对特定查询优化表?
- 最喜欢的性能调整技巧
- 首先,请确保数据库运行状况良好,如果可能,请对其运行DBCC DBREINDEX,如果无法承受性能损失,请运行DBCC INDEXDEFRAG并更新统计信息。
- 以合理的采样时间运行Profiler,足以捕获大多数典型功能,但是对持续时间大于10秒的过滤,我们根本不在乎只花几毫秒的时间,甚至不用看那些。
- 现在我们有了运行时间最长的查询,现在就可以解决这些问题。得到最充分利用的查询,在查询分析器中查看执行计划,花一些时间来理解它们,并在必要时添加索引以加快检索速度
- 着眼于创建涵盖索引;如果只需要SELECT LASTNAME,FIRSTNAME ...,则在需要时更改应用程序(如果正在执行SELECT * FROM ...)。
- 重复进行探查器采样,持续时间为5秒,3秒等,直到性能达到期望。
在分析了索引和查询之后,我们可能希望仅使用更多的硬件。可能还有更多演出的公羊。
我认为最好使OLTP类型的数据保持非规范化状态,以防止核心数据受到"污染"。那会咬你一路走的。
如果瓶颈是由于报告或者只读需求,我个人认为除标准化的"生产"表外,非标准化的报告表也没有问题。创建一个流程以汇总到使查询变得快速所需的任何级别。一个简单的SP或者夜间过程(该过程定期地汇总和非规范化仅以只读方式使用的表)通常会在用户体验方面产生巨大的差异。
毕竟,如果没有人因为速度变慢而不想使用系统,那么拥有理论上干净,完全标准化的数据集有什么好处?
有趣的...这里有很多答案。
rdbms / os版本是64位吗?
在我看来,性能下降了好几倍。部分原因当然是由于索引。我们是否考虑过以与数据存储方式一致的方式对某些表进行分区?含义是,根据数据的输入方式(基于顺序)创建分区。因为大多数索引都是静态的,所以这将为我们带来很多性能提升。
另一个问题是xml数据。我们是否在使用xml索引?摘自在线书籍(2008)"使用主XML索引,支持以下类型的辅助索引:PATH,VALUE和PROPERTY。"
最后,当前设计的系统是否可以运行/执行很多动态sql?如果是这样,由于需要生成,重新生成和很少执行计划,因此我们将无法使用内存。我称此为内存搅动或者内存颠簸。
高温超导
几百万条记录对于SQL Server来说是一个很小的数据库。它可以处理大量连接所需的terrabytes数据,而不会费力。我们可能遇到设计问题或者写得很差的查询。
上线之前进行性能测试的荣誉。在我们投入数月或者数年的生产后,要修复这些东西要困难得多。
我们所做的可能是一个错误的选择。如果我们进行非规范化,则需要设置触发器以确保数据保持同步。是你做的吗?它增加了多少插入和更新时间?
我的第一个猜测是我们没有在外键上放置索引。
关于可能出问题的其他猜测包括过度使用以下内容:
相关子查询
标量函数
视图调用视图
游标
EAV表
缺乏可燃性
使用select *
不良的表设计也可能使其难以获得良好的性能。例如,如果表太宽,则访问它们的速度将变慢。如果我们经常将数据转换为另一种数据类型以使用它,那么我们将其存储不正确,这将始终拖累系统。
动态SQ1可能比存储的proc更快,但可能没有。对于性能,这里没有正确的答案。为了提高内部安全性(不必在表级别设置权限)和易于对数据库进行更改,存储的proc更好。
我们需要运行探查器并确定最慢的查询是什么。还查看所有非常频繁运行的查询。每天运行成千上万次查询时,进行很小的更改就可以得到很大的回报。
我们还应该去获得一些有关性能调优的书。这些将完成整个过程,因为性能问题可能是由许多原因引起的:
数据库设计
查询设计
硬件
索引编制
等等。
没有一种快速修复方法,如果不维护数据完整性,随机地进行非规范化可能会给我们带来更大的麻烦。