【问题标题】:How to increase the performance of a Database?如何提高数据库的性能?
【发布时间】:2011-01-01 17:30:40
【问题描述】:

我曾在公司多次设计数据库。为了提高数据库的性能,我只寻找规范化和索引。

如果您被要求提高具有大约 250 个表和一些具有数百万条记录的表的数据库的性能,您会寻找哪些不同的东西?

提前致谢。

【问题讨论】:

  • 这有点含糊,你的意思是插入性能,读取性能,具体是什么。
  • 在某些表中插入性能和在某些表中读取性能。 :)
  • 标准化并不总能提高性能
  • @Superfilin:那么bad数据fast比较好? ;)
  • @OMG,我只是警告说它不总是好的。规范化更多地针对数据结构质量而不是性能。有很多文章说明了非规范化如何提高性能。

标签: sql database sql-server-2005 performance


【解决方案1】:

优化逻辑设计

逻辑级别是关于查询和表本身的结构。首先尝试最大化这一点。目标是在逻辑级别访问尽可能少的数据。

  • 拥有最高效的 SQL 查询
  • 设计支持应用程序需求的逻辑架构(例如列的类型等)
  • 设计权衡以比其他用例更好地支持某些用例
  • 关系约束
  • 标准化

优化物理设计

物理层处理非逻辑考虑,如索引类型、表参数等。目标是优化一直是瓶颈的IO。调整每张桌子以适应它的需要。小表可以永久加载到 DBMS 缓存中,低写入率的表可以与高更新率的表有不同的设置以占用更少的磁盘空间等。根据查询,可以使用不同的索引等。你可以使用物化视图等透明地非规范化数据。

  • 表参数(分配大小等)
  • 索引(组合、类型等)
  • 系统范围的参数(缓存大小等)
  • 分区
  • 非规范化

先尝试改进逻辑设计,然后再改进物理设计。 (两者之间的界限是模糊的,所以我们可以争论我的分类)。

优化维护

必须正确操作数据库才能尽可能保持高效。这包括一些可能对性能产生影响的维护任务,例如

  • 使统计数据保持最新
  • 定期对关键表重新排序
  • 磁盘维护
  • 所有系统的东西都让服务器运行起来

【讨论】:

    【解决方案2】:

    这是一个非常模糊的问题。

    你说你在寻找索引,但你不能孤立地看待索引。您必须查看正在运行的查询、执行计划、正在使用的索引以及它们的使用方式。 Profiler 工具有助于确定哪些查询效率低下。

    除此之外 - 确保制定了维护计划。在繁重的事务性数据库中,您应该至少每周更新一次统计信息和碎片整理/重建索引。

    如果您有基础架构,请查看您的文件和文件组设置。如果可能,您应该尝试将大型且经常使用的表和/或索引放在不同的物理驱动器上。如果您有任何非常大的表,您可能会考虑对它们进行分区。

    如果您仍然遇到性能问题,非规范化有时会有所帮助 - 但这完全取决于具体情况。

    我将就此打住——不希望这个答案成为世界上最随机的 SQL 性能提示列表。我建议您更具体地说明您认为性能问题在哪里,并告诉我们更多有关数据库的信息(大小、当前索引策略、事务频率、您需要生成的任何大型报告等)

    【讨论】:

      【解决方案3】:

      压缩。对于我尝试过的绝大多数负载,使用压缩是一种巨大的搭便车。减少数据大小意味着减少 I/O 意味着更好的吞吐量。在 SQL Server 2005 中,压缩选项是有限的 (vardecimal)。但我会认真考虑单独升级到 2008 进行页面压缩。或者 2008 R2,如果您经常使用 nvarchar 来获得 Unicode 压缩。

      数据保留。建立保留策略并积极删除旧数据。更少的数据意味着更少的 I/O,意味着更好的吞吐量。通常这被视为操作而非设计,但我喜欢将此问题视为应用程序设计问题。

      当然,我假设您已经监控了每一个查询,以确保没有人进行愚蠢的端到端表扫描。

      更多的性能提升器主要用于操作或部署,而不是设计:维护(碎片整理、索引重建等)、I/O 和存储设计等。

      最后但并非最不重要的是了解各种交钥匙解决方案的隐藏成本。例如,复制或数据库镜像。

      【讨论】:

        【解决方案4】:

        我在 MySpace 的工作是“性能增强 DBA/开发人员”。我想说规范化和索引是高性能数据库的要求,但您必须真正分析您的表结构和索引才能真正释放数据库设计的力量。

        以下是我对您的一些建议;

        1. 了解数据库引擎。深入了解下划线 I/O 结构对于设计适当的索引或表大有帮助。使用 PerfMon 和 Profiler,除了您对读/写 I/O 的了解之外,您还可以在关于什么是格式良好的表/索引解决方案的理论背后添加一些非常具体的数字。

        2. 了解聚集索引和非聚集索引之间的区别以及何时使用哪种索引。

        3. 使用 sys.dm_os_waiting_tasks 和 sys.dm_os_wait_stats DMV。他们会告诉你应该在哪里努力减少等待时间。

        4. 使用 DBCC SET STATISTICS IO/TIME ON,并评估您的执行计划以查看一个查询是否会减少或增加页面读取次数或持续时间。

        5. DBCC SHOWCONTIG 会告诉您您的表是否严重碎片化。从性能的角度来看,开发人员和 Jr. DBA 经常忽略这一点 - 但是,这会对您拥有的页面读取数量产生非常大的影响。如果一个表具有 20% 的扩展页密度,这意味着您读取的数据大约是对表及其索引进行碎片整理时的数据的 5 倍。

        6. 评估脏读(nolock, read uncommited)。如果您可以取消毫秒精度的读取,请保存锁!

        7. 考虑取出不必要的外键。它们在开发环境中很有用,而不是在高性能事务系统中。

        8. 大表中的分区会产生很大的不同 - 前提是设计得当。

        9. 应用程序更改 - 如果您可以为异步事务安排批量更新,请将它们放入无索引堆并按计划进行处理,这样您就不会经常更新您大量查询的表。

        10. 永远永远永远!!!使用相同的数据类型变量查询目标列;例如,以下语句对 smallint 列使用 bigint 变量:

        声明@i bigint 设置@i = 0

        从 MyTable 中选择 * Col01SmallInt >= @i

        在评估索引/表页面的过程中,查询引擎可能会选择将您的 smallint 列数据转换为 bigint 数据类型。相反,请考虑更改您的 varialbe 类型,或者至少在您的搜索条件中将其转换为 smallint。

        1. SQL 2005/08 在管理应用程序中为您提供“报告”,查看有关索引执行情况的报告。他们是否被扫描、搜索?你最后一次表扫描是什么时候?如果它是最近的,则您的索引没有满足所有必要的查询。如果您的索引几乎没有被使用(查找或扫描)但不断更新,请考虑删除它。它可以为您节省很多不必要的行锁和键锁。 ..

        这就是我能想到的。如果您遇到更具体的问题,我会为您提供更具体的答案..

        【讨论】:

          【解决方案5】:

          对于您的规范化和索引工具包,对于非常大的表,您可能还需要考虑对表进行分区的优缺点。但是你已经有了关键的。

          【讨论】:

          • Enterprise/Developer 版只能对表进行分区
          • 您可以使用任何版本的视图进行自己的本地分区。
          【解决方案6】:

          您可以做很多事情,其中​​很多已经在上面提出了建议。我会看的一些(按此顺序):

          • 错误/日志 - 许多数据库引擎都有报告工具来指出数据库中的问题区域。从这里开始,看看是否有什么可以让您立即专注的事情。
          • 数据保留 - 检查业务规范应保留数据多长时间,确保将所有旧数据移至数据仓库以保持表大小较小。 (如果只需要最近 3 个月的数据,为什么还要保留 5 年的数据?)
          • 寻找表扫描,如果有帮助的话,索引数据(你必须根据表写入来衡量这个)。您的服务器日志可能会帮助您查找表扫描。
          • 工作的原子元素,是否在到达提交点之前,某些写入会在不同的表上保持锁定?是否可以简化这些工作元素或移动提交点以提高性能?这是您需要开发人员查看代码的地方。
          • 寻找长时间运行的 SQL 语句,是否可以提高效率?有时,结构不佳的查询确实会使应用程序陷入困境。您可能需要建议更改编码以提高性能。
          • dba 领域:查看表的分配方式:页面大小、多个段等。这是供应商提供的诊断工具派上用场的地方,因为它们通常可以建议您如何根据使用历史构建表。有经验的 dba 在这里会很有用。
          • 查找硬件/网络瓶颈。这是您需要硬件人员的地方。 :)

          这些真的很高,我也想看看你的数据库引擎供应商建议的性能改进。

          此外,我会根据我的老板愿意支付的费用以及我有多少时间来衡量这样的清单。 ;)

          希望这会有所帮助。

          【讨论】:

            【解决方案7】:

            如果查询对任务非常关键,您可能需要考虑de-规范化,以减少每个查询的表查找次数。 除此之外,如果您需要超出索引和反规范化所能执行的更多性能,您可能需要查看程序方面的内容:缓存、优化查询/存储过程等。

            【讨论】:

            • @BlueRaja :我们也可以在数据库中进行缓存吗?
            【解决方案8】:

            为了提高性能,您需要首先监控您的数据库。您可以跟踪然后将其加载到 sql server profiler 中以找出最慢的查询。之后你就可以专注于它们了。

            您还可以使用动态视图和管理功能来找出缺少哪些索引。您还可以检索有关现有索引的统计信息,例如索引使用情况和丢失的索引。

            【讨论】:

            • 我会说,在设计过程中你还没有任何东西要监控。
            • 有很多人可以在绘图板上看到设计中的性能问题......
            • 还有很多性能问题在设计时是看不到的。您可能会发现一个在一天中只执行几次的慢速存储过程和一个执行多次的较快存储过程。如果你没有实际的统计数据,你会优化哪一个?
            【解决方案9】:

            优化用于访问该数据库的查询是最重要的。仅仅通过添加索引并不能保证查询会使用它们。

            【讨论】:

              【解决方案10】:

              我们还没有写过关于性能方面的文章:

              硬件。

              数据库是高度 I/O 驱动的。移动到更快的硬盘驱动器应该会提高数据库查询的速度。在多个快速硬盘驱动器之间拆分数据库可能会进一步改善它。

              【讨论】:

                猜你喜欢
                • 2010-10-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2023-03-08
                • 1970-01-01
                • 2016-12-25
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多