影响SQL Server数据库应用性能的几个常见因素
性能问题是困扰数据库用户的常见问题之一。经常会有人因为遇到性能问题,质疑SQL Server处理大型数据应用的能力。其实,作为一个在市场上经营了二十多年,出了好几代版本的数据库产品,SQL Server作为一个企业级数据库的能力,是毋庸置疑的。在实际应用中,数据量达到几百GB,甚至上TB级,并发连接数超过1、2千个,每秒钟处理的请求数量超过1000多个的SQL Server,现在已经很多了。在国内的一些大客户那里,我们也越来越多地看到这样的SQL Server。
那为什么有些SQL Server能跑得那么强劲,而很多用户的数据库还只有几十GB,就感觉跑不动了呢?在谈性能问题的常见原因之前,我们先谈谈SQL Server的几个和性能有关的重要特性。了解这些特性,对设计一个高效的数据库应用,是非常必要的。
1. SQL Server要访问的数据,是一定要缓冲在内存里的
不管是要查询的数据,还是要修改的数据,SQL Server在运行客户端发过来的语句,处理这些数据之前,都要检查其访问的数据是否在内存中。如果不在内存中,SQL Server会先把存储数据的页面从磁盘调入内存,然后再做真正的数据处理。
数据处理完毕后,SQL Server不会马上把这段数据缓存丢弃。只要SQL Server不缺内存,先前访问过数据页面就会一直缓存在SQL
Server进程的地址空间里。这样,如果下次有其他用户要访问同样的数据记录,SQL
Server就可以马上在内存中进行处理,而不需要再到磁盘上去找。
这样的设计,可以最大程度的重用内存,提高SQL Server的处理速度。同时也决定了,SQL Server是一个非常喜欢大内存的应用程序。
2. 如果SQL Server没有空闲的内存,而用户需要访问新的数据,SQL会把以前缓存的数据挑选一部分从内存中清除,腾出空间来缓存新的数据
SQL Server不会无限制地申请内存。它会根据用户的设置,以及系统的内存数量,计算自己的最大内存数。如果当前的内存大小以及达到了这个上限,SQL就不会再向Windows申请更多的内存。这样的机理,可以保证SQL Server和Windows,以及运行在同一台机器上的其他应用程序和平共处。
当SQL Server的内存数已经达到最大值,内存空间已经缓存满各种各样的数据页面,而用户又要访问新的、还没有缓存在内存里的数据时,SQL
Server会根据现有数据访问的频度,把最老的、最不经常被人访问的数据,从内存里清除,从而腾出空间来缓存现在客户要访问的新数据。
所以最理想的状态,是用户要访问的数据永远都缓存在内存里,SQL Server从来都不需要到磁盘上去找。这也是数据库性能最佳的情况。这时候SQL Server几乎从来不需要做磁盘读。
如果经常发生用户要访问的数据不在内存里的情况,SQL Server就会被迫不停地在内存和磁盘之间倒腾数据,性能会受到严重的影响。而这时候,你会看到SQL在经常地作磁盘读的动作。
3. 表格中数据的组织与访问,和聚集索引的选择密切相关
SQL Server的一个显著的特点,是表格里数据的存储,是按照聚集索引所在字段的值排序的。而非聚集索引是建立在聚集索引结构之上的。如果一张表格没有聚集索引,数据是按照堆的方式存储,没有任何顺序。
对于同样的数据量,SQL Server对一个有聚集索引的表格的管理,远远比没有聚集索引的表格要有效。绝大多数情况下,一张大表如果想要有良好的性能,就必须有一个合适的聚集索引。没有聚集索引,只加非聚集索引,也不能够达到优化的性能。
这是SQL Server的一个很重要的特点。
4. 在缺省的事务隔离级别下,同一条记录上的读操作和写操作是互斥的
SQL Server实现的是ANSI 标准的四个隔离级别。在Read Committed这个缺省的隔离级别上,读操作会申请S锁,修改操作会申请X锁,S锁和X锁互斥。所以同一条记录上不能同时进行读操作和写操作。
业界的有些其他数据库产品,缺省使用行版本控制方式实现事务隔离,如果一个用户在修改某一条记录、但是没有提交事务,而另一个用户要读同一条记录,它会让第二个用户读到第一个人修改之前这条记录的值。所以读操作和写操作是可以同时进行的。
这种版本控制的隔离级别,并发度当然比SQL Server的要高,读写操作之间产生阻塞的几率要小。可是它的事务隔离效果和SQL是不同的。例如,对于某个银行账户的查询,假设账户里原来有1万元,用户A开始一个事务,将账户里的1万元转出。在转出这个动作还没有完成时,用户B来查询账户余额。使用版本控制,用户B可以马上得到结果:1万元,但是这个结果其实很有可能已经过时。使用SQL Server,用户B必须等到用户A转帐完成才能查到余额,但是他得到的一定是一个最新的值。
这两种隔离级别其实反映了两种用户需求,不能讲哪种好,哪种不好。喜欢版本控制这种隔离级别的用户,如果想要在SQL
Server里有同样的并发度,可以选择SQL里面的Snapshot Isolation Level(这个功能在SQL 2005里引入)。这样,SQL里的读写操作就不互斥了。
上面的这几个特征,决定了SQL Server的很多行为特点。如果跑在SQL Server上应用程序没有很好地按照上述的特征设计,就容易遇到各种各样的性能问题。
在现实应用中,SQL Server性能问题的常见原因有下面几点。
1. 索引的设计不够优化,从而迫使语句经常使用全表扫描的执行计划
如果没有好的索引帮助,SQL Server查询任何一条记录都有可能不得不把整张表都扫描一遍。这个在数据库比较小的时候影响不大,因为SQL能够把所有数据都缓存在内存里,就算是全表扫描也不会太慢。随着数据量增大,内存会放不下。全表扫描的负担会越来越重,到最后会严重影响SQL
Server的整体性能。
这是一个很常见的SQL Server越跑越慢的原因。
2. 大的表格没有聚集索引,或者聚集索引建立在不合适的数据列上
对于没有聚集索引的表格,如果里面的记录数以万计或者更多,管理和查询都会增加很多开销。一个经验是,对于一个要经常使用的任何大表格,请建立聚集索引。索引所在的数据列,应该是一个或者几个重复性的记录不是很多的数据列。
业界的一些其他数据库可能对聚集索引这个概念不是非常强调,或者使用其他的方法管理表格。所以如果把非SQL
Server的数据库迁移到SQL Server里,一定要重新检查索引结构,按照SQL Server的特点,调整索引设置。否则迁移后在SQL Server上得不到好的性能,是很正常的。
3. 用户需要经常访问的数据量,远大于机器的内存数
前面我们已经说过,SQL
Server要操作的数据,是必须要缓存在内存里的。如果终端所有用户要经常访问的数据量的总和,远远超出SQL Server所拥有的内存数量,那SQL就会不得不在内存和磁盘间反复换页。这时候的SQL性能下降,可能就不是一两个数量级了。
用户需要经常访问的数据量的大小,通常跟以下几个因素有关。
a.用户发过来的语句定义
如果语句里有良好的条件约束,那数据量就能得到控制。如果条件约束性不强,那数据量就会随着表格里的记录数增长而增长。一个例子是,用户总是查询“今年的某某数据”。那在一年开始的时候,查询肯定很快。到年底时候的数据量可是一月份的12倍。那时候访问的数据量也很可能就是12倍。
b.SQL Server是否能够利用索引,使用Seek的方式找到数据,而不是扫描全表
如果没有好的索引,哪怕用户要访问的数据只是表格里的很小一部分,SQL可能也需要遍历整个表格。在这种情况下,也会出现表格越大,SQL跑得越慢的情况。如果索引设计地比较优化,SQL Server的数据访问量,不应该跟表格的大小有着绝对的关系。
c.应用程序的性质
数据库应用基本可以分两大类:OLTP类型的,和Data Warehouse类型的。前者会处理大量的小事务,比如病人挂号、超市结帐、仓库进货等。这种应用用户发过来的请求不会很复杂,每次要处理的数据量也比较小,但是要求的响应速度要很快。有可能0.5秒的等待都会带来性能问题。所以对这种应用,其访问的数据应该保证总是缓存在内存里。
Data Warehouse类型的应用主要是做数据分析和整理,经常是为了产生一些报表。这种应用主要以查询为主,肯定会访问大量的数据,会出现数据库越大,访问的数据量越多的情况。但是客户端可以容忍一定时间的等待。对于这种应用,其访问的数据不在内存里关系也不大。
对于OLTP类型的应用,应该尽量保证用户经常要访问的数据能够长时间地缓存在内存里。所以在设计应用逻辑和数据库时,就要有所考虑,控制用户访问的数据量,建立有效的索引,避免全表扫描。在管理上,也要有历史数据归档的机制,控制整个数据库的大小。如果证明用户需要访问的数据量就是比内存大,升级内存也是需要考虑的方案。
对于报表类型的应用,因为访问的数据量会很大,磁盘换页是难以避免的。当然良好的索引设计,对性能也会很有帮助。
要避免的情况,是同一个SQL Server既在运行OLTP类型的应用,又时不时地在运行报表类型的应用。它们两者会产生很大的相互干扰,对OLTP应用的响应速度会产生破坏性的影响,而且很难用调整数据库设计,或者升级硬件的方法轻易解决。
4. 数据库应用是从其他非SQL Server的架构下直接移植过来的
前面已经谈过,SQL Server缺省的事务隔离级别是Read Committed,和其他数据库可能不一样。另外,很多应用是通过调用数据库控件的接口来访问数据库的,而不是直接调用SQL语句或者存储过程。要达到同一个目的,程序里有很多种实现的方法。有些方法可能在其他数据库上性能会不错,但是到SQL
Server上有可能就要换一个做法,或者换一种驱动。再加上不同的数据库系统对指令的写法可能有不同的建议,表格上的索引要求也不一样。所以要在SQL
Server上实现良好的性能,就必须对迁移过来的应用在SQL Server平台上进行优化。没有测试、优化而直接移植过来的应用,常常不能发挥SQL Server的长处,性能欠佳。
分享到:
相关推荐
在“SQL Server数据库应用辅导”中,我们可能涉及以下几个核心知识点: 1. 数据库设计:理解数据库的ER模型(实体-关系模型),学习如何设计表结构,包括主键、外键、索引的设置,以及数据类型的选取,确保数据的...
### SQLServer数据库应用程序性能优化方法 #### 一、引言 SQL Server 是 Microsoft 开发的一款高性能的客户端/服务器模式下的数据库管理系统,它采用单进程、多线程的技术,在核心层实现了数据完整性控制,具备...
本书首先介绍了 Delphi 和SQL Server 2000 开发的必备知识,然后完整地介绍了几个使用Delphi 开发SQL Server 2000数据库应用程序的实例,包括人事工资管理系统、仓库管理系统、车队管理系统和超市管理系统。...
### SQL Server数据库的性能分析和优化策略研究 #### 一、引言 随着信息技术的快速发展,企业纷纷构建了自己的信息系统,数据库作为信息系统的核心组成部分,其性能直接影响到整个系统的稳定性和响应速度。传统上...
在开始讨论SQL Server数据库的备份与还原之前,我们需要了解几个基本的概念。 - **MDF 文件**: 这是SQL Server数据库的主要数据文件,存储了数据库的所有数据。每一个SQL Server数据库至少包含一个MDF文件。 - **...
### SQLSERVER数据库性能优化分析 #### 一、问题分析 **1.1 死锁** 在SQL Server数据库中,死锁是一种常见的性能问题。当多个事务互相等待对方释放资源时,就会形成死锁。例如,进程A锁定了资源B,进程B锁定了...
影响数据库性能的因素主要包括以下几个方面: 1. SQL语句的设计不当。如果SQL语句设计得过于复杂,将可能导致系统的响应时间变得非常长。设计良好的SQL语句应该是简洁、高效的。 2. 并发用户数量过多。如果数据库...
SQL Server 数据库导入导出的方法 SQL Server 数据库导入导出是数据库管理员和开发者常用的操作,目的是将数据库备份到本地或网络存储设备中,以便在需要时恢复数据库或将数据库迁移到其他服务器上。下面将详细介绍...
Sql Server 数据库超时问题的解决方法 Sql Server 数据库超时问题是指在使用 Sql Server 数据库时,出现的等待响应时间过长或超时的...通过这些方法,可以解决 Sql Server 数据库超时问题,提高数据库性能和稳定性。
- **概述**:内存是影响SQL Server性能的关键因素之一,正确设置内存分配可以大幅提升系统性能。 - **实践建议**: - 根据服务器的实际可用内存和操作系统需求来调整SQL Server的最大内存限制。 - 在Windows ...
【SQL Server数据库技术期末大作业 代码与数据库】 在SQL Server数据库技术的学习中,期末大作业通常会涵盖多个核心概念,以检验学生对数据库管理、查询优化和事务处理的理解。根据提供的文件名,我们可以推断出这...
本项目“Winform+SQL Server数据库图书管理系统”是采用C#编程语言开发的一款高效、实用的图书管理软件,它运用了三层架构的设计模式,结合SQL Server 2016数据库,为用户提供了一套完整的图书管理解决方案。...
安装过程中,SQL Server 2000会自动创建几个关键的系统数据库: 1. **master**数据库:存储所有SQL Server系统信息,包括登录信息、系统设置、初始化信息以及其他系统和用户数据库的相关数据。 2. **model**数据库...
在本资源"C#语言和SQL Server数据库基础第7章.zip"中,我们聚焦于C#编程语言和SQL Server数据库的基础知识。C#是Microsoft开发的一种面向对象的编程语言,广泛应用于构建Windows桌面应用、Web应用以及游戏开发。SQL ...
在本文中,我们将深入探讨如何使用VBA(Visual Basic for Applications)通过ADO(ActiveX Data Objects)连接到SQL Server数据库并执行数据查询。这个过程在Excel中尤其常见,因为VBA是Excel内置的编程环境,允许...
视图和存储过程机制是 SQL Server 中的一种安全机制,视图是从一个或几个基本表(视图)中导出的虚表。在数据库系统中,可以利用视图通过授予用户操作特定视图的权限,限制用户访问表的特定行和特定列来保证数据的...
《SQL Server数据库应用与开发》是一本专注于教授SQL Server数据库技术的教材,旨在帮助学习者掌握SQL Server在实际应用中的各种技术和开发方法。这本电子教案由李德有和彭德林两位专家编著,提供了丰富的教学资源,...
在"SQL Server 2012 数据库技术及应用第四版"中,我们可能会学习到以下几个关键知识点: 1. **SQL Server 2012的新特性**:理解SQL Server 2012相比前代版本的改进,如AlwaysOn高可用性解决方案、Columnstore索引、...
教程主要面向三类读者:SQL的初学者、SQL Server数据库的初学者和SQL Server数据库开发人员。对初学者而言,教程通过实例和理论相结合的方式深入浅出地介绍Transact-SQL语言,而对开发人员则提供一个实用的参考手册...
本文将从账号管理、认证授权、日志配置、通信协议、设备其他安全要求等几个方面对Sql Server数据库系统的加固规范进行详细介绍。 一、账号管理和认证授权 账号管理是数据库系统安全的第一步,Sql Server数据库系统...