标题：性能调优
简介
什么是性能调校呢？一般是当用户抱怨“太慢了”、“性能不足”、“软硬件需要升级  了”等问题时，提供较佳的性能。但不是要解决用户所说的“这系统毁了”、“它不会工作了”等问题，这可能需要的是备援回滚、提高系统可获得性（HA high Availability）等解决方案。但就数据库系统而言，规划高可获得性的架构（如SQL Cluster、Mirroring、Log Shipping、Replication等）不会提升系统性能，还要注意是否降低了性能。
现象
而一般观测性能问题的现象有：
        系统响应速度太慢。
        每秒所完成的系统输出/入低于预期。
        相同的环境，但每秒钟所完成的批操作较先前少。
        系统资源（如CPU、内存、硬盘或网络等）长时间处于耗尽的状态。
通常调校的目标是以用户的期望为依据，除非你的数学与信息基本功非常扎实，否则很难知道调校的极限在哪。因此，我们的目标往往是符合用户的期盼即可
基线
调校性能的第一个工作应该是建立性能的基线（baseline），所需的类型有：
        昔日系统正常运行时的数据。
        调校前系统的各种数据。
        用户希望达到的目标。
基线是用来比较的，任何性能调校的动作都应该依凭数据，不要诉诸情绪。笔者常听到工程师说“今天的性能感觉比较差了”或是“现在系统响应比较慢了”。这种话是我们要帮用户解决问题的起因，但不应该是工程师讲的话。人的感觉非常不准，可能是心情不好，可能是对工作不满意，对系统的包容力就比较差，感觉就不好了。
系统响应比较慢，要知道正常是多少、慢了多少、时间差是多少、数据量多少、多少人同时上线、处理量多少等。也就是要有基线，有客观的数据，这才有好的调校基础。而通常笔者碰到的是：工程师与用户们忙了一天，精疲力竭后，会安慰自己“性能比较好了”。
如前文所述，一般要将用户的期待量化，例如，用户可以接受系统的响应时间是3~5 秒。而用户的期待通常是来自于以下方面。
工作需求：如一定要在某个时间点前完成，一秒之内要完成多少交易量才能满足多人访问等。以往系统的使用经验。一些性能数据值（benchmark）：不管是厂家提供的，还是业界提出的标准值。其他用户使用类似功能的经验。
为什么讨论这个呢？因为期待要合理。不要第一次开车开奔驰，然后误以为全世界的汽车开起来都要像这样。或许你会觉得这不可能发生。但事实上，若以往的系统是以Windows Form为基础，现在一模一样的功能，但改为以Web Form为基础，在相同的硬件上，可能响应就比较慢。毕竟以往从SQL Server或COM+/MTS直接传数据给编译过的VB 前端程序呈现结果，系统架构简单有效率且交互功能丰富。而Web版的ASP/ASP. NET应用程序要先将SQL Server或COM+/MTS的结果数据转换成HTML，再用效率也不高的HTTP通信协议返回到前端，最后还要浏览器遵从HTML 或DHTML 指示符，当前绘制界面，整体系统的性能当然不如以往的程序架构。
若用户端的机器本身很快，使用者或许还感受不到这个差异，然而笔者曾碰到的情况：使用古老的机器，但要求Web Form 长得和Win Form 一样，并且功能还要更多，而能忍受的响应时间相同，这就难如登天了。
支出
另外，性能调校代表着成本（cost）的支出，成本可能是实质的钱，也可能是工程师的时间与精力，用户的忍耐等待。在理想状况下，是把系统中最贵的部分发挥到极限，能够以最低的成本来发挥系统最大的性能。若是自己开发的程序，这往往代表着硬件采购是系统开发中最贵的部分，因此，会采取重新设计系统的解决方式，如数据库逻辑使用方式重新切割、查询方式大量重载、以消耗内存的方式减少对硬盘的访问等。你可能要花掉数个工程师个把月的时间，才得以将架构重新规划，程序全面重载，或许花费如此的人力成本还不如直接更新设备，但性能调校的总体成本（total cost）并不容易计算。
笔者遇到的大部分状况是管理者会挑眼前最节约成本的事情先做。一般来说，就是要工程师着手调架构，可能是数据库的设计，也可能是程序代码重载，忙了个把月后声明失败，最后还是花钱买机器。这种仅看当前最低成本的做法有几个弊端：
用户苦等一两个月，最后还是换机器，他们会觉得工程师能力不足。实际上浪费了人力成本。一阵子后，性能问题又再度浮现。
在动手调校前应该对整个系统的各个瓶颈点了然于胸，各花多少成本可以解决，而该瓶颈调整后，整体系统性能可以提升多少。以笔者曾调校的系统为例，整体设计是用IE呈现IIS执行ASP的结果，ASP 调用COM+，COM+访问SQL Server。系统刚上线时，总响应时间是7秒钟，但用户可以接受的时间是3 秒钟。程序中，个别的时间消耗是IE花费2秒钟（因为前端PC老旧，而执行操作很复杂），ASP 处理时间0.5 秒钟，COM+处理时间4秒钟，SQL Server处理时间0.5秒钟。
前端PC 数量太大，要升级成本太高。因此，大家都觉得先调后端吧，这时就算工程师花了九牛二虎之力，将三种服务器的性能都提升一倍，也就是让原来各服务器处理时间的总和5秒钟降为2.5秒钟，但系统整体时间还是要4.5秒钟。
用户骂了一个月之后，在不准更改功能的窘境下，还是要更新前端PC，这时大家就难堪了。所以，事前的整体评估很重要，告知用户能期待什么？最后底线是什么？才有可能让大家都接受调校的结果。
性能的基线应该都是可以量化的，例如，响应时间、单位时间可执行的批处理数量、单位时间可以处理的数据量、同时上线人数等，都可以求出最大值、最小值、平均值、总数等。针对要调校的目标，先获取数据后，才可以评估调校的方向是否正确。另外，对系统各环节的性能极限应尽可能地评估一下，不要耗了极大的功夫，才发现其实早已经把某一部分发挥到极限了，再怎么做都不可能提升多少性能，这时你可能需要变更用户需求、系统架构或必须更换软硬件。
有些值是当前可以算出来的，例如，直接将用户访问数据的T-SQL语句当前执行一遍，可以看出执行该语句的时间，在SQL Server本机上通过管理工具执行一次，在远程网络上再执行一次，可以约略知道网络是否有影响等。但某些数据可能要特别建立一些环境来测试，例如，没有用户，空机的时候某个工作的执行效率如何？有多人上线时，又是如何反应？原本某个工作每秒钟可以完成多少次，加上什么运行程序后，每秒钟只剩几次等。
另外，如压力测试时，要仿真多大的数据量，多少人同时上线等，建立这些基线的数据就较为困难，因为仿真的环境要尽量与真实相同。因为不同的数据模型，SQL Server 会建立不同的执行计划，若是以随机数产生的数据，往往与真正的数据类型不符，使索引判断、选择如何做Join等都会大不相同。
这些基线的数据应该越详尽越好，不要泛泛地取些值就拿来比较。笔者碰过一位工程师拿着代表某大型系统执行性能的4张图，上面标着中央处理器、主存储器、硬盘与网络，各有着一条弯弯曲曲描述性能的线，除了内存的线长时间在天上之外，其余的都不高，他就有了结论：内存要加大。当然，你让不懂信息技术的路人甲看这4张图，跟他解释图形的意义，问他要如何调性能，他也会说要加内存，因为就只有这张图看起来和其他3张长得不一样。
如果公司的钱用不完，这样的调校似乎就足够了，全部都靠扩大硬件来提升性能。但就前述的现象，可能要问的是，内存与硬盘缓存盘交换是否频繁，数据缓存区的高速缓存击中率（cache hit ratio）是否低于90% ，以进一步确认是否为内存不足才拖慢整体性能。说不定是数据库锁定，也说不定是程序有Bug造成内存遗失（memory leak），或是程序本身的Bug造成性能不足等。
若真的是内存不足，是否还可以调校？说不定是数据库系统的设置一开始要占用极大的缓存区，所以，大部分的内存都被它拿走，但整体来说并没有有效使用内存 。因此，哪个程序吃掉了大部分的资源？谁是主要调校的目标？什么样的方向或指针代表调校有效？诸此种种都应该落到文字上，如此可以整理较为清晰的思路，并有可讨论的交集，否则一堆没有共识的专家，恐怕只会众说纷纭，皆能证明不是自己的错，但祸首是谁却说不出来，最后落到会而不议，议而不决的窘况。
目标
这些落于纸上的目标应越明确越好，例如上述的情况，若目标是 “我想要调低内存的使用率，因为它的值太高了”就不如“我想要调低某个程序开始获取内存的设置，因为它可能吃掉太多的内存，但实际没有用到这么多，而其他的应用程序没有足够的内存，导致整体系统性能不佳”。后者的描述有目标，且可以比较，因为实际调整后可以观察调低内存的程序执行起来是否有问题，整体的性能与没调整前是否有差异。
除了以文档描述基线、调校的目标外，还可以以文档描述所用的工具，如评估性能的程序、真实应用程序的片段功能、各种资源的性能监视程序、压力测试程序等。同时，有越详细的步骤越好。性能调校可能是一再的错误尝试，因为大部分的状况都是扑朔迷离的，无法一眼看出问题所在，需要改改这个，看看是否比较好，再修修那个，看看结果如何。若没有文档记录，你可能会在性能调校的大迷宫中打转，做一些类似而重复的事情，但总理不出头绪。
尝试列出系统中各个组件合理的性能消耗，可以帮助你理清整个系统访问中，各个组件所占的性能消耗比例，哪些部分有可以调整的空间。另外，再搭配调整该部分的成本有多高，让你了解调整的优先级，并对系统的极限有更佳的认识。