我在网络项目(asp.net)工作了大约六个月。最终产品即将投入使用。该项目使用SQL Server作为数据库。我们已经使用一些大量数据进行了性能测试,结果表明,当数据变得太大时,性能会下降,比如200万行(超时问题,延迟响应等)。起初我们使用完全规范化的数据库,但现在我们由于性能问题(减少连接)使其部分规范化。首先,这是正确的决定吗? 另外,当数据量变得非常大时,可能的解决方案是什么?客户未来会增加多少?
我想进一步补充:
答案 0 :(得分:30)
在方案中,几百万行不是特别大的数据库。
假设我们正在讨论OLTP数据库,在没有首先确定瓶颈的根本原因的情况下进行非规范化是一个非常非常糟糕的想法。
您需要做的第一件事是在有代表性的时间段内分析您的查询工作负载,以确定大部分工作的完成位置(例如,如果您使用的是SQL Server,则使用SQL事件探查器)。查看查询执行的逻辑读取次数乘以执行次数。一旦确定了执行率最差的十大查询,就需要详细检查查询执行计划。
我会在这里出去(因为通常就是这种情况),但如果你的问题不是,我会感到惊讶
此SO answer介绍如何进行配置文件以查找工作负载中性能最差的查询。
答案 1 :(得分:13)
正如那句老话“正常直到它受伤,反正常直到它起作用”。
我喜欢这个!这通常是不能再被接受的事情。我可以想象,回到DBASEIII
次,你不能一次打开超过4个表(除非更改你的一些AUTOEXEC.BAT参数并重新启动计算机,啊!),有对非正规化有一些兴趣。
但是现在我看到这个解决方案类似于等待海啸给他的草坪浇水的园丁。请使用可用的喷壶(SQL分析器)。
不要忘记,每当你对数据库的一部分进行非规范化时,随着代码中的错误风险的增加,你进一步调整数据库的能力就会降低,这会使整个系统的可持续性越来越低。
答案 2 :(得分:8)
200万行通常不是超大型数据库,具体取决于您存储的信息类型。通常,当性能下降时,您应该验证索引策略。 SQL Server数据库引擎优化顾问可能会对此有所帮助。
答案 3 :(得分:3)
可能有一百万个原因;在使用“架构更改”之前,使用SQL事件探查器和查询分析器确定为什么您的查询变慢。所有你需要做的就是创建一些索引并安排“更新统计信息”......但正如我所说,Profiler和查询分析器是查找正在发生的事情的最佳工具。
答案 4 :(得分:1)
起初我们使用的是完全规范化的数据库,但现在由于性能问题(减少连接),我们部分地进行了部分规范化。
正如那句老话“正常直到它受伤,反正常直到它起作用”。
在大型,重型dbs中看到一定程度的非规范化以帮助提高性能是相当普遍的,所以我现在不用太担心它,只要你的表现仍然在你想要的地方,你的管理“非规范化”字段的代码不会变得太繁重。
当数据大小变得非常大时,可能的解决方案是什么?客户未来会增加多少?
对应用程序的域名不太了解,很难说你如何能够证明它的未来性,但是在流量较大的数据库中将最近使用的旧数据拆分成单独的表是一种相当常见的方法 - 如果95%的话您的用户正在查询过去30/45天内的数据,其中包含“live_data”表格,其中包含最近60天的数据,旧版本的“old_data”可以帮助您提升效果。
一个好主意是确保您设置了广泛的性能监视,以便在数据和负载增加时测量数据库的性能。如果您发现性能明显下降,可能是时候重新访问索引了!
答案 5 :(得分:1)
这可能不是正确的决定。识别所有数据库交互并对其进行独立分析,然后找出有问题的交互并制定策略以最大限度地提高性能。同时打开数据库上的审核日志并挖掘它们可能会提供更好的优化点。
答案 6 :(得分:1)
首先确保您的数据库相当健康,如果可能,请运行DBCC DBREINDEX,DBCC INDEXDEFRAG并在您无法承受性能损失时更新统计信息。
运行Profiler一段合理的采样时间,足以捕获大部分典型功能,但过滤时间大于10秒,你不关心只花几毫秒的事情,不要甚至不看那些。
现在您的查询运行时间最长,可以将snot调出来;得到最多的那些,查看查询分析器中的执行计划,花一些时间来理解它们,在必要时添加索引以加速检索
看看创建覆盖索引;如果需要改变应用程序,如果它正在执行SELECT * FROM ...当它只需要SELECT LASTNAME,FIRSTNAME ....
重复分析器采样,持续时间为5秒,3秒等,直到性能达到您的预期。
答案 7 :(得分:0)
我们一直试图使用尽可能接近“真实世界”的数据库进行开发。这样你可以避免像这样的很多问题,因为如果他的连接在调试过程中保持超时,那么任何一个开发人员都会精神错乱。调试Sql性能问题的最佳方法IMO是Mitch Wheat建议的;配置文件以查找有问题的脚本并从它们开始。优化脚本可以带您走远,然后您需要查看索引。还要确保您的Sql Server具有强大的功能,尤其是IO(磁盘)非常重要。别忘了;缓存为王。记忆很便宜;买多点。 :)
答案 8 :(得分:0)
首先,正如许多人所说,几百万行并不大。 我正在处理的当前应用程序有几个表都有超过一亿行,其中所有行都已归一化。
我们确实遭受了一些糟糕的性能,但这是由于使用默认的表统计信息设置引起的。相对于表的总大小插入少量记录,即将一百万条记录插入到包含超过100万条记录的表中,不会导致表统计信息的自动更新,因此我们会得到较差的查询计划正在生成串行查询而不是并行。
关于是否正确决定反规范,取决于你的架构。您是否必须定期执行深度查询,即加载连接以获取您经常需要访问的数据,如果是这样,那么部分取消可能是一种前进的方式。
但之前您已检查过索引和表格统计策略。
检查您是否使用了合理的,结构良好的查询,并确保您的联接形式良好。检查您的查询计划,您的查询实际上正在解析您期望的方式。
正如其他人所说,SQL Profiler /数据库引擎优化顾问确实做得很好。
对我来说,非规范化通常接近我要做的事情列表的底部。
如果您仍然遇到问题,请检查您的服务器软件和硬件设置。
答案 9 :(得分:0)
你做任何有用的事都是对的。
......只要你意识到以后可能会付出代价。无论如何,听起来你正在考虑这个问题。
要检查的事项:
请参阅我关于一般性能提示的其他帖子:
答案 10 :(得分:0)
分析了索引和查询后,您可能只想通过更多硬件。还有一些ram演出可能会成功。
答案 11 :(得分:0)
我认为最好保持您的OLTP类型数据非规范化,以防止您的核心数据被“污染”。那会让你不耐烦。
如果瓶颈是由于报告或只读需求,我个人认为除了规范化的“生产”表外,还有非规范化报告表的问题;创建一个流程,以便达到使查询变得快速所需的任何级别。一个简单的SP或每晚进程定期汇总和非规范化仅以只读方式使用的表格通常会对用户体验产生巨大影响。
毕竟,如果没有人想要使用你的系统,那么拥有理论上干净,完全标准化的数据集有什么用呢?
答案 12 :(得分:0)
有趣......这里有很多答案..
rdbms / os版本是64位吗?
在我看来,性能下降了几倍。部分原因当然是由于索引。您是否考虑过以与数据存储方式一致的方式对某些表进行分区?意思是,根据数据的输入方式创建分区(基于顺序)。由于大多数索引都是静态的,因此这会带来很多性能提升。
另一个问题是xml数据。你在使用xml索引吗?从联机丛书(2008)“使用主XML索引,支持以下类型的二级索引:PATH,VALUE和PROPERTY。”
最后,系统目前是否设计用于运行/执行大量动态sql?如果是这样,您将需要从内存中进行解除,因为需要生成,重新生成并且很少重新生成计划。我称这种记忆流失或记忆颠簸。
HTH
答案 13 :(得分:0)
几百万条记录是SQL Server的一个小型数据库。它可以处理数TB的数据,有很多连接,没有汗水。您可能遇到设计问题或编写的查询非常糟糕。
在您上线之前进行性能测试的荣誉。在生产数月或数年之后,修复这些东西要困难得多。
你所做的可能是一个糟糕的选择。如果进行非规范化,则需要设置触发器以确保数据保持同步。是你做的吗?它增加了多少插入和更新时间?
我的第一个猜测是你没有把索引放在外键上。
关于可能出现的错误的其他猜测包括:过度使用诸如: 相关子查询 标量函数 观看呼叫视图 游标 EAV表 缺乏可靠性 使用select *
糟糕的桌面设计也可能难以获得良好的性能。例如,如果您的表太宽,访问它们会更慢。如果您经常将数据转换为其他数据类型以便使用它,那么您将其存储错误,这将永远拖累系统。
动态SQl可能比存储过程更快,但可能不会。这里没有一个正确的答案来表现。对于内部安全性(您不必在表级别设置权限)并且易于对数据库进行更改,存储过程更好。
您需要运行探查器并确定最慢的查询。另请查看经常运行的所有查询。一个小的改变可以带来很大的回报,每天都会运行多次查询。
你也应该去看一些关于性能调整的书。这些将帮助您完成整个过程,因为性能问题可能是由许多因素造成的: 数据库设计 查询设计 硬件 索引 等
如果不保持数据完整性,没有一个快速修复和随机非规范化会让您遇到更多麻烦。