SQL Server 性能优化之——系统化方法提高性能

原文 http://www.cnblogs.com/BoyceYang/archive/2013/06/15/3138142.html

阅读导航

1. 概述

2. 范逻辑数据库设计

3. 使用高效索引设计

4. 使用高效的查询设计

5. 使用技术分析低性能

6. 总结

 

1. 概述

在比较大的范围内找出能够大幅提高性能的区域,并且专注于分析这个区域,这是最有效的优化SQL Server性能的方式。否则,大量的时间和精力可能被浪费在不能提高很大性能的区域。在这里并没有讨论关于多用户并发所带来的性能问题。

能获得最大性能提高的区域一般是:逻辑数据库设计,索引设计,查询设计。然而,最大的性能问题经常由于缺乏这些方面研究的原因造成。如果性能是被列为一个需要关注的问题,聪明的做法是首先专注于这些方面, 因为性能的大幅提高经常是用相对较小的时间精力完成。

下面开始进入正题。

2. 规范逻辑数据库设计

合理规范性的逻辑数据库设计可以产生最佳性能。大量的窄表是标准数据库的特性。少量的宽表是非标准数据的特性。高度标准数据库通常关联着复杂的表的 联合查询,这个可能损害数据库的性能。不管怎么样,SQL Server优化在快速查询、高效联接、可用有效索引方面是非常有效的,下面是规范化的好处:

  • 如果是窄表,应该加快排序和创建索引
  • 如果是宽表,最好使用聚集索引
  • 索引往往是越窄的表,越应该精确
  • 更好的利用段去控制表的物理空间
  • 每个表的索引越少,对提高UPDATE操作的性能越有帮助
  • 越少的NULLs列,越少的冗余数据,越能增加数据库的紧凑性

对于SQL Server,标准化将有助于提升而不是损害性能。随着标准化的提高,因此需要一定数量并且复杂的表连接来检索数据。只要标准化不会导致很多查询出现超过四个表的连接,就应进行标准化进程。

如果逻辑数据库设计已经固定,并且不可能进行整体重新设计,而且通过研究表明一个大表存在性能瓶颈,在这样的情况下,可以有选择性的对这个大表进行 标准化。如果过存储过程进行访问数据,那么架构的改变不会影响应用程序。如果不是这样,可以通过创建视图来隐藏这种改变,因为视图可以产生单个表的错觉。

3. 使用高效索引设计

不像很多非关系系统,不把关系索引考虑作为逻辑数据库设计的一部分。索引能被删除、添加和更新,除了影响性能以外,不会影响数据库架构或者应用程序 设计。实现良好的SQL Server性能,高效索引设计是非常重要的。由于这些原因,不要犹豫展示不同索引带来的性能改变吧。

大多数情况下,优化器将可靠地选择最高效的索引。所有的策略应该提供良好的索引优化的选择,相信这是正确的决定。这可以在多种情况下,减少分析时间并且能提供良好的性能。

接下来介绍索引。检查SQL查询的WHERE子句,因为这个是优化的主要焦点。在WHERE子句中列出的列都有可能成为索引的备选。假如有太多的语句需要检查,挑选有代表性的一组,或者仅仅是速度缓慢的那组。

最好使用窄索引。窄索引比混合索引和复合索引更加高效。窄索引每页行越多,索引级别应该越低,这样才能提高性能。SQL Server优化只是维护统计数据在复合索引最重要的列上。因此,如果复合索引的第一列可选择性很差,那么就不优化这个索引。

优化器可以快速、高效的分析成百上千的索引和表连接的可能性。有更多的窄索引提供给优化器,优化器就会有更多可能的选择,这对性能很有帮助。有较少的宽索引、复合索引提供给优化程器,优化器只有很少选择的可能性,这对性能会有影响。

索引数目太多性能可能会降低,因为涉及到更新这些索引的开销。然而,大量的面向更新操作需要更多的读操作,而不是写操作。假如,尝试新索引时提高了性能,那就不要犹豫,使用这个所以吧。

使用聚集索引。适当的使用聚集索引可以极大的提升性能。甚至聚集索引可以使UPDATE和DELETE操作提速,因为这些操作需要很多读操作。可能 每个表只有单一的聚集索引,因此,要灵活地利用这个索引。返回行数的查询或者涉及一个范围值的查询都是一个可能被聚集索引提高性能的候选。

例子:

   1:  SELECT * FROM PHONEBOOK
   2:   
   3:  WHERE NAME = ‘李雷’
   4:   
   5:  SELECT * FROM MEMERTABLE
   6:   
   7:  WHERE MEMBER_NO > 5000 AND MEMBER_NO < 6000

通过约束,上面提到的NAME和MEMBER_NO列,对于非聚集索引可能不是一个适合的候选。尽量在返回很少行数据的列上使用非聚集索引。

检查列数据的唯一性。这样将帮助决定,什么样的列作为聚集索引、非聚集索引、无需索引的备选。

查询语句检查数据的唯一性,例子:

   1:  SELECT COUNT (DISTINCT COLNAME) FROM TABLENAME

这个语句将返回一个列中不重复值的数量。在表中比较这个数量和总的行数。在一个一万行的表中,5000个不重复值的列对于非聚集索引可能是一个很好 的备选,20个不重复值的列可能最适合聚集索引,3个不重复值的列根本就不需要使用索引。这些仅仅是个例子,不是一成不变的规则。记住把索引建立在WHERE查询子句列出的每一个列上。

在索引选择时,查询语句返回行数也是一个重要的因素。优化器会考虑非聚集索引花费在每个返回行至少一页I/O的成本。以这样的速度,并不需要很长的时间就可以变得更高效的扫描整个表。理性对待结果集,要么限制结果集的大小,要么使用聚集索引定位巨大结果集。

4. 使用高效的查询设计

某些查询语句本身是资源密集型。这关系到基本数据和索引在大多数RDBMSs(关系型数据库管理系统)的常见问题,而不是在特定SQL Server中。它 们并不低效,优化器将会尽可能实现高效的查询语句。然而,它们是资源密集型,SQL面向结果集的本性可能使它们出现低效。优化器的智能程度不可能消除这些 结构的固有资源成本。和更加简单的语句相比,他们内在的消耗更大。尽管SQL Server使用最优的访问计划,但还是会有限制的。

例如:

  • 大型结果集
  • IN和OR语句
  • 高度非唯一WHERE子句
  • !=(不等于)
  • 某些列函数,比如SUM
  • WHERE子句中的表达式或数据转换
  • WHERE子句的局部变量

有些因素可能需要使用这些查询语句结构。如果优化器可以限制结果集,然后再应用资源密集型的查询,那么他们的影响将会减少。

例如:

   1:  低效: SELECT SUM(SALARY) FROM TABLE
   2:   
   3:  高效: SELECT SUM(SALARY) FROM TABLE WHERE ZIP='98052'
   4:   
   5:  低效: SELECT * FROM TABLE WHERE LNAME=@VAR
   6:   
   7:  高效: SELECT * FROM TABLE WHERE LNAME=@VAR AND ZIP='98052'

在第一个例子中,SUM操作使用索引并不能使其加速。每行都需要被读和求和。设想在ZIP列有一个索引,优化器将可能使用这个来初始限制结果集,然后再应用SUM函数。这可能会更快。

在第二个例子中,局部变量直到运行时才被赋值。然而优化器无法拖延到运行时才选择访问计划,必须在编译时进行选择。然而,在编译期间,当生成访问计 划时,@VAR的值还不能确定,因此不能使用输入的@VAR作为索引选择。可以使用AND子句对结果集进行限制。使用存储过程是一个可选技术,这样可以传 递参数,将参数赋值给存储过程中@VAR值。

大多数RDBMSs的大型结果集是很耗费性能。可以尝试不返回大型结果集到客户端作为最终数据选择。允许数据库后台执行预定函数,并限定结果集的大小,这种做法效率很高。

5. 使用技术分析低性能

首先分离查询,或者分离比较慢的查询。当有少数SQL查询速度慢,经常表现为整个应用程序速度慢。对能够显示生成SQL的工具,使用这个工具的诊断或调试模式记录生成的SQL。使用嵌入式SQL工具会更加简单。分离速度慢的查询之前,先做一下下面的步骤:

  • 单独运行疑似速度慢的语句,使用工具(例如ISQL、SAF)验证实际上是不是很慢。
  • 使用SET STATISTICS IO ON,检查语句的I/O消耗和已选择的访问计划。优化器的目的是最小的I/O。记录逻辑I/O。以这个为基准测量改进成果
  • 如果查询涉及视图或者存储过程,从中提取这些语句并单独运行。当尝试使用不同索引时,访问计划是可以改变。
  • 有些表可以生成I/O作为触发器运行,这时要注意可能和这些表有关系的触发器和视图。
  • 检查速度慢的语句表的索引。利用之前列出的技术检查是否有更好的索引,如果有必要就修改。
  • 改变索引后重新运行查询,并观察I/O和访问计划的改变。
  • 改进工作完成,运行主程序看看所有的性能是不是有所提升。

检查程序的I/O或CPU限制的行为。通常这个对确定查询语句是否在I/O或CPU临界状态很有用。我们要花费精力在提高真正的性能瓶颈上,例如, 如果一个查询是CPU临界状态,就算增加更多的内存给SQL Server也太可能有性能的提高,当然更多的内存还是能提高缓存命中率。下面的步骤是检查SQL Server的I/O和CPU临界状态:

  • 使用OS/2 CPU监控程序。
  • 当运行查询时,如果CPU使用率保持很高(>70%),这表明是CPU临界状态。
  • 当运行查询时,如果CPU使用率保持很低(<50%),这表明也是CPU临界状态。
  • 使用STATISTICS IO比较CPU利用率信息

6. 总结

SQL Server能够提高大型数据库的性能。要挖掘这个性能的潜力,需要有高效的数据库设计、索引和查询语句。这些区域是最可能成为捕获到重大性能提升的备选区域。尝试使用索引是一个很特别建议。通常,系统化的方法在分析性能问题上,不仅投入时间少,而且能产生巨大性能提升。

 

在此特别感谢@守望dreamstar对本篇文章的支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/547765.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

yum搭建lnmp的最简单方法

相信有些刚刚接触web开发的小伙伴对于服务器上搭建web环境还不太了解&#xff0c;今天手把手教大家搭建lemp的线上环境&#xff0c;您需要做如下一些准备&#xff1a; 阿里云或者其他服务商的云主机一台云主机已安装Centos 7了解ssh、vim 好的&#xff0c;相信大家已经做好准备…

java opencv 平移_Java中使用opencv

Java中使用opencvJava中使用opencv零、前言作为图像处理出身&#xff0c;不仅仅要会C图像处理、matlab图像处理、python图像处理、最起码也得会java图像处理&#xff0c;当然我最终还都用的是opencv这个机器视觉库了。今天简单介绍一下java中如何使用opencv。一、配置库(1)官网…

子域名跨越的问题

子域名不支持ajax直接提交&#xff0c;但支持form表单直接提交。

Linux利用PROMPT_COMMAND实现审计功能

这个系统审计&#xff0c;记录什么用户&#xff0c;在什么时间&#xff0c;做了什么操作。 然后将查到的信息记录到一个文件里。一。 配置1. 在/etc/profile 文件的最后&#xff0c;添加如下2行代码&#xff1a;export HISTORY_FILE/var/log/File_history/date %Y-%m-%d.logexp…

CentOS7 安装 NextCloud

NextCloud 的安装依赖LAMP环境&#xff0c;即 Linux Apache MySQL(Mariadb) PHP&#xff0c;所以在装 NextCloud前最好先装好这些&#xff0c;并且保证已经可用。 为了方便&#xff0c;本文在运行shell命令时都是以管理员用户身份运行&#xff08;root权限下运行&#xff0…

jQuery 插件取url参数[jquery.url.js]的使用以及文件下载

方法一、 如题&#xff0c;直接上调用代码&#xff1a; jQuery.url.param("c") “c”就是当前url中的参数&#xff0c;记得要引用jquery.js和jquery.url.js jquery.url.js 下载 方法二、 function GetQueryString(name) {var reg new RegExp("(^|&)"…

java 存储png文件_vue图片上传及java存储图片(亲测可用)

1.前言在使用elementui的upload组件时,我一直无法做到上传的图片和其他数据一起提交。单纯的上传文件,java的存储图片的方式也有局限性。我知道的后端保存图片有两种方式:一种是直接存储到数据库中(base65和blob都能做到),一种是存储在服务器上的一个文件夹,数据库保存图片地址…

看视频学编程之最最基础的基础(1)

------- Windows Phone 7手机开发、.Net培训、期待与您交流&#xff01; ------- C#语法&#xff1a; 1、从上到下一条条的依次执行。过去的就让他过去吧&#xff0c;不会返回头执行&#xff1a;int i13;int i25;int i3i1i2;i19;。大小写敏感。String和string 都行是另外一个问…

苹果系统使用之输入法的呈现与设置问题

新装的系统&#xff0c;总是纠结的出现各种问题。今天解决的就是装了Mac OS X 10.6&#xff08;苹果系统&#xff09;之后&#xff0c;输入法找不到&#xff0c;用快捷不能设置的问题。 刚开始使用mac os x 系统&#xff0c;其实说用也谈不上&#xff0c;因为本人是使用公司的电…

利用Seafile搭建私有文件同步云盘

安装 Seafile 所需环境 如果你的CVM系统为Ububtu系统&#xff0c;请查看Ububtu系统安装教程&#xff0c;如果系统为CentOS&#xff0c;请参考CentOS操作系统安装教程&#xff0c;本文以Ubuntu Server 16.04.1 LTS为例。 Ubuntu系统 这里我们使用apt包管理器进行安装&#xf…

java更改用户邮箱_git修改user.name 和user.email

今天刚刚入门了下git&#xff0c;&#xff0c;然后初始化的时候将用户名弄错了。。。就很气啊。然后网上找了半天都找不出一个可靠的修改全局用户名和邮箱的方法。。最后还是自己摸索出来了。。其实也很简单。首先进入git bash0&#xff1a;输入$ git config --list可以查看配置…

js堆栈溢出的问题

js是最令程序员头疼的问题了&#xff0c;不是语法也不是使用头疼&#xff0c;而是调试头疼&#xff0c;虽然有很方便的各种各样的调试工具&#xff0c;但经管这样有时候一个疏忽的小问题&#xff0c;会导致各种各样的奇怪问题的出现&#xff0c;今天笔者的同事就出现了这样的问…

halcon 17 cuda cudnn 深度学习环境搭建

如果你想安装halcon17&#xff0c;那么很简单&#xff0c;硬盘剩余空间2G,内存超过256M&#xff0c;操作系统win7以上即可。 但显然我们的要求不仅如此&#xff0c;因为我们期待已久的深度学习功能。 详细要求见下表 必备环境&#xff1a;电脑必须要有 NVIDIA 独立显卡&#x…

给java程序员网址_程序员常用网址,必须收藏

金山快盘 http://www.kuaipan.cn/login/ yijianfeng_vip163.com115 网盘 http://my.115.com/ yijianfeng_vip163.com.六间房图片外链刷流量工具-软件 http://www.safe-120.com/sites/yijianfeng/sh…

Format Currency Sample

2019独角兽企业重金招聘Python工程师标准>>> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"&…

jQuery.html()方法ie下不能设置html代码的问题

jQuery一般来说还是很好用的&#xff0c;但有时候它也会有些问题的&#xff0c;比如jQuery的html()方法设置html代码&#xff0c;在一种情况下&#xff0c;ie6、ie7、ie8 下是不能设置html代码的。本文说的问题只针对ie8&#xff08;包括ie8&#xff09;以下的浏览器。 1.什么情…

深度学习-服务端训练+android客户端物体识别实战(caffe入门教程+mobilenet+ncnn+android)

文章目录 背景 物体识别简介 自动驾驶 淘宝京东使用物体识别技术公司业务需求 深度学习简介 深度学习的位置 深度学习概念深度学习优势 深度学习基础知识 感知机 激活函数多层感知机卷积神经网络 卷积层 * 池化层 模型训练 前向传播 * 反向传播与参数优化 深度学习服务端框…

java数组怎么倒循环_java – 用于数组倒计时的反向循环

我收到错误..Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10at Reverse.main(Reverse.java:20).语法没有错,所以我不确定为什么编译时会出错&#xff1f;public class Reverse {public static void main(String [] args){int i, j;System…

解压zip,解决中文乱码

Project p new Project(); Expand e new Expand(); e.setProject(p); e.setSrc(file); e.setOverwrite(false); e.setDest(new File(savepath)); /* * * ant下的zip工具默认压缩编码为UTF-8编码&#xff0c; …

二维码的生成(可设置大小)以及插件下载地址

本文写的二维码生成是基于jQuery和jquery.qrcode.min.js插件的&#xff0c;本文将介绍两种方法和方式&#xff0c;仅供朋友选择和取舍。本文最下面附有插件的下载地址&#xff01; 方式1&#xff1a; 基于jquery.qrcode.min.js插件生成&#xff0c;代码如下&#xff1a; <h…