zoukankan      html  css  js  c++  java
  • SQLServer查询速度慢的原因

    查询速度慢的原因很多,常见如下几种: 
    1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)
    2、I/O吞吐量小,形成了瓶颈效应。 
    3、没有创建计算列导致查询不优化。 
    4、内存不足 
    5、网络速度慢 
    6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 
    7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷)
    8、sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。
    9、返回了不必要的行和列 
    10、查询语句不好,没有优化可以通过如下方法来优化查询 : 
    二二、、相应解决方法建议相应解决方法建议 
    1、把数据、日志、索引放到不同的I/O设备上,
    RAID0上,SQL2000不在支持。数据量(尺寸)
     
    2、纵向、横向分割表,减少表的尺寸(sp_space
     
    3、升级硬件 
     
    4、根据查询条件,建立索引,优化索引、优化访
    子要适当(最好是使用默认值0)。索引应该尽
    引的创建),不要对有限的几个值的字段建单一
     
    5、提高网速; 
    6、扩大服务器的内存,Windows 2000和SQL server 2000能支持4-8G的内存。配置虚拟内
    存:虚拟内存大小应基于计算机上并发运行的服务进行配置。运行 Microsoft SQL Server?
    2000 时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的 1.5 倍。如果另外安装
    了全文检索功能,并打算运行 Microsoft 搜索服务以便执行全文索引和查询,可考虑:将
    虚拟内存大小配置为至少是计算机中安装的物理内存的 3 倍。将 SQL Server max server
    memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半)。 
     
    7、增加服务器CPU个数;但是必须明白并行处理串行处理更需要资源例如内存。使用并行还
    是串行程是MsSQL自动评估选择的。单个任务分解成多个任务,就可以在处理器上运行。例
    将表锁住,禁止其他的联接访问表,后果严重。 
     
    14、SQL的注释申明对执行没有任何影响 
     
    15、尽可能不使用光标,它占用大量的资源。如果需要 row-by-row 地执行,尽量采用非光
    标技术,如:在客户端循环,用临时表,Table变量,用子查询,用Case语句等等。游标可
    以按照它所支持的提取选项进行分类: 只进 必须按照从第一行到最后一行的顺序提取行。
    FETCH NEXT 是唯一允许的提取操作,也是默认方式。可滚动性 可以在游标中任何地方随机
    提取任意行。游标的技术在SQL2000下变得功能很强大,他的目的是支持循环。有四个并发
    选项 READ_ONLY:不允许通过游标定位更新(Update),且在组成结果集的行中没有锁。
    OPTIMISTIC WITH valueS:乐观并发控制是事务控制理论的一个标准部分。乐观并发控制用
    于这样的情形,即在打开游标及更新行的间隔中,只有很小的机会让第二个用户更新某一行。
    当某个游标以此选项打开时,没有锁控制其中的行,这将有助于最大化其处理能力。如果用
    户试图修改某一行,则此行的当前值会与最后一次提取此行时获取的值进行比较。如果任何
    值发生改变,则服务器就会知道其他人已更新了此行,并会返回一个错误。如果值是一样的,
    服务器就执行修改。 选择这个并发选项�OPTIMISTIC WITH ROW VERSIONING:此乐观并发控
    制选项基于行版本控制。使用行版本控制,其中的表必须具有某种版本标识符,服务器可用
    它来确定该行在读入游标后是否有所更改。在 SQL Server 中,这个性能由 timestamp 数
    据类型提供,它是一个二进制数字,表示数据库中更改的相对顺序。每个数据库都有一个全
    局当前时间戳值:@@DBTS。每次以任何方式更改带有 timestamp 列的行时,SQL Server 先
    在时间戳列中存储当前的 @@DBTS 值,然后增加 @@DBTS 的值。如果某 个表具有 timestamp
    列,则时间戳会被记到行级。服务器就可以比较某行的当前时间戳值和上次提取时所存储的
    时间戳值,从而确定该行是否已更新。服务器不必比较所有列的值,只需比较 timestamp 列
    即可。如果应用程序对没有 timestamp 列的表要求基于行版本控制的乐观并发,则游标默
    认为基于数值的乐观并发控制。 SCROLL LOCKS 这个选项实现悲观并发控制。在悲观并发控
    制中,在把数据库的行读入游标结果集时,应用程序将试图锁定数据库行。在使用服务器游
    标时,将行读入游标时会在其上放置一个更新锁。如果在事务内打开游标,则该事务更新锁
    将一直保持到事务被提交或回滚;当提取下一行时,将除去游标锁。如果在事务外打开游标,
    则提取下一行时,锁就被丢弃。因此,每当用户需要完全的悲观并发控制时,游标都应在事
    务内打开。更新锁将阻止任何其它任务获取更新锁或排它锁,从而阻止其它任务更新该行。
    然而,更新锁并不阻止共享锁,所以它不会阻止其它任务读取行,除非第二个任务也在要求
    带更新锁的读取。滚动锁根据在游标定义的 SELECT 语句中指定的锁提示,这些游标并发选
    项可以生成滚动锁。滚动锁在提取时在每行上获取,并保持到下次提取或者游标关闭,以先
    发生者为准。下次提取时,服务器为新提取中的行获取滚动锁,并释放上次提取中行的滚动
    锁。滚动锁独立于事务锁,并可以保持到一个提交或回滚操作之后。如果提交时关闭游标的
    选项为关,则 COMMIT 语句并不关闭任何打开的游标,而且滚动锁被保留到提交之后,以维
    护对所提取数据的隔离。所获取滚动锁的类型取决于游标并发选项和游标 SELECT 语句中的
    锁提示。锁提示 只读 乐观数值 乐观行版本控制 锁定无提示 未锁定 未锁定 未锁定 更新
    重要的手段。例如医院的住院费计算。
     
    26、MIN() 和 MAX()能使用到合适的索引。 
     
    27、数据库有一个原则是代码离数据越近越好,所以优先选择 Default,依次为
    Rules,Triggers, Constraint(约束如外健主健 CheckUNIQUE……,数据类型的最大长度等
    等都是约束),Procedure.这样不仅维护工作小,编写程序质量高,并且执行的速度快。 
     
    28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌INsert来插入(不
    知 JAVA 是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务
    器受到字符后又将他转换成二进制值.存储过程就没有这些动作: 方法:Create procedure
    p_insert as insert into table(Fimage) values (@image), 在前台调用这个存储过程传
    入二进制参数,这样处理速度明显改善。 
     
    29、Between 在某些时候比 IN 速度更快,Between能够更快地根据索引找到范围。用查询优
    化器可见到差别。 select * from chineseresume where title in ('男','女') Select *
    from chineseresume where between '男' and '女' 是一样的。由于in会在比较多次,所
    以有时会慢些。 
     
    30、在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因
    为索引也耗费大量的资源。他的创建同是实际表一样。 
    31、不要建没有作用的事物例如产生报表时,浪费资源。只有在必要使用事物时使用它。 
    32、用OR的字句可以分解成多个查询,并且通过UNION 连接多个查询。他们的速度只同是
    否使用索引有关,如果查询需要用到联合索引,用 UNION all 执行的效率更高.多个 OR的字
    句没有用到索引,改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。 
     
    33、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure
    来代替她。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。我们看视图的
    本质:它是存放在服务器上的被优化好了的已经产生了查询规划的SQL。对单个表检索数据
    时,不要使用指向多个表的视图,直接从表检索或者仅仅包含这个表的视图上读,否则增加
    了不必要的开销,查询受到干扰.为了加快视图的查询,MsSQL增加了视图索引的功能。 
     
    34、没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户端执行。它们增加了
    额外的开销。这同UNION 和UNION ALL一样的道理。 
    select  top  20  ad.companyname,comid,position,ad.referenceid,worklocation,
    convert(varchar(10),ad.postDate,120)  as  postDate1,workyear,degreedescription
    FROM  jobcn_query.dbo.COMPANYAD_query  ad  where  referenceID
    果返回大的结果采用存储过程 
     
    42、不要在一句话里再三的使用相同的函数,浪费资源,将结果放在变量里再调用更快 
     
    43、SELECT COUNT(*)的效率教低,尽量变通他的写法,而EXISTS快.同时请注意区别: select
    count(Field of null) from Table 和 select count(Field of NOT null) from Table 的
    返回值是不同的!!! 
     
    44、当服务器的内存够多时,配制线程数量 = 最大连接数+5,这样能发挥最大的效率;否
    则使用 配制线程数量<最大连接数启用 SQL SERVER 的线程池来解决,如果还是数量 = 最大
    连接数+5,严重的损害服务器的性能。
     
    45、按照一定的次序来访问你的表。如果你先锁住表 A,再锁住表 B,那么在所有的存储过
    程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再锁
    定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁很难被发
    现 
     
    46、通过SQL Server Performance Monitor监视相应硬件的负载 Memory: Page Faults / sec
    计数器如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。
    Process: 
    a、% DPC Time 指在范例间隔期间处理器用在缓延程序调用(DPC)接收和提供服务的百分
    比。(DPC 正在运行的为比标准间隔优先权低的间隔)。 由于 DPC 是以特权模式执行的,DPC
    时间的百分比为特权时间 百分比的一部分。这些时间单独计算并且不属于间隔计算总数的
    一部 分。这个总数显示了作为实例时间百分比的平均忙时。 
      b、%Processor Time计数器  如果该参数值持续超过95%,表明瓶颈是CPU。可以考虑增
    加一个处理器或换一个更快的处理器。 
      c、% Privileged Time 指非闲置处理器时间用于特权模式的百分比。(特权模式是为操作
    系统组件和操纵硬件驱动程序而设计的一种处理模式。它允许直接访问硬件和所有内存。另
    一种模式为用户模式,它是一种为应用程序、环境分系统和整数分系统设计的一种有限处理
    模式。操作系统将应用程序线程转换成特权模式以访问操作系统服务)。 特权时间的 % 包
    括为间断和 DPC 提供服务的时间。特权时间比率高可能是由于失败设备产生的大数量的间
    隔而引起的。这个计数器将平均忙时作为样本时间的一部分显示。    
      d、% User Time 表示耗费 CPU 的数据库操作,如排序,执行 aggregate functions 等。
    如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该
    值。 Physical Disk: Curretn Disk Queue Length计数器该值应不超过磁盘数的1.5~2倍。
    要提高性能,可增加磁盘。 SQLServer:Cache Hit Ratio 计数器该值越高越好。如果持续
    低于80%,应考虑增加内存。 注意该参数值是从SQL Server启动后,就一直累加记数,所
    以运行经过一段时间后,该值将不能反映系统当前值。  
     select * from @local_variable where Fid > 40 and fid <= 60 
    end 的不同 
      begin 
       create table #temp (FID int identity(1,1),ReferenceID varchar(20)) 
       insert into #temp (ReferenceID) 
       select top 100000 ReferenceID from chineseresume order by updatedate 
       select * from #temp where Fid > 40 and fid <= 60 drop table #temp 
    end 
    三、、安全方面的建议安全方面的建议  
         1.安装最新的服务包
     
         为了提高服务器安全性,最有效的一个方法就是升级到 SQL Server 200
    3a (SP3a)。 
     
         另外,您还应该安装所有已发布的安全更新。
     
         2.使用 Microsoft 基线安全性分析器(MBSA)来评估服务器的安全性
     
         MBSA 是一个扫描多种 Microsoft 产品的不安全配置的工具,包括
    Microsoft SQL Server 2000 Desktop Engine (MSDE 2000)。它可以在本地
    过网络运行。该工具针对下面问题对 SQL Server 安装进行检测:
     
         1) 过多的sysadmin固定服务器角色成员。 
     
         2) 授予sysadmin以外的其他角色创建 CmdExec 作业的权利。 
     
         3) 空的或简单的密码。 
     
         4) 脆弱的身份验证模式。 
    5) 授予管理员组过多的权利。 
    6) SQL Server数据目录中不正确的访问控制表
    7) 安装文件中使用纯文本的sa密码。 
    sa 帐户应该总拥有一个强健的密码,即使在配置为要求 Windows 身份验证的服务器
    该如此。这将保证在以后服务器被重新配置为混合模式身份验证时,不会出现空白或脆
    sa。
    要分配sa密码,请按下列步骤操作:
    1) 展开服务器组,然后展开服务器。 
    2) 展开安全性,然后点击登录。 
    3) 在细节窗格中,右键点击SA,然后点击属性。 
    4) 在密码方框中,输入新的密码。 
     6.限制 SQL Server服务的权限 
        SQL Server 2000 和 SQL Server Agent 是作为 Windows 服务运行的。每个服务必须
    与一个 Windows 帐户相关联,并从这个帐户中衍生出安全性上下文。SQL Server允许sa 登
    录的用户(有时也包括其他用户)来访问操作系统特性。这些操作系统调用是由拥有服务器
    进程的帐户的安全性上下文来创建的。如果服务器被攻破了,那么这些操作系统调用可能被
    利用来向其他资源进行攻击,只要所拥有的过程(SQL Server 服务帐户)可以对其进行访
    问。因此,为 SQL Server 服务仅授予必要的权限是十分重要的。
        我们推荐您采用下列设置:
        1) SQL Server Engine/MSSQLServer
        如果拥有指定实例,那么它们应该被命名为MSSQL$InstanceName。作为具有一般用户
    权限的Windows 域用户帐户运行。不要作为本地系统、本地管理员或域管理员帐户来运行。
        2) SQL Server Agent Service/SQLServerAgent 
        如果您的环境中不需要,请禁用该服务;否则请作为具有一般用户权限的 Windows 域
    用户帐户运行。不要作为本地系统、本地管理员或域管理员帐户来运行。 
    重点: 如果下列条件之一成立,那么 SQL Server Agent 将需要本地 Windows 管理
    员权限: 
    2000 中,下列文件可能受到影响:默认安装时:Program FilesMicrosoft SQL
    ServerMSSQLInstall文件夹中,以及指定实例的:Program FilesMicrosoft SQL Server
    MSSQL$Install文件夹中的sqlstp.log, sqlsp.log和setup.iss
     
         如果当前的系统是从 SQL Server 7.0 安装升级而来的,那么还应该检查下列文件:
    %Windir% 文件夹中的setup.iss以及Windows Temp文件夹中的sqlsp.log。
     
         Microsoft 发布了一个免费的实用工具 Killpwd,它将从您的系统中找到并删除这些
    密码。
     
         10.审核指向 SQL Server 的连接
     
         SQL Server 可以记录事件信息,用于系统管理员的审查。至少您应该记录失败的 SQL
    Server 连接尝试,并定期地查看这个日志。在可能的情况下,不要将这些日志和数据文件
    保存在同一个硬盘上。
     
         要在 SQL Server 的 Enterprise Manager 中审核失败连接,请按下列步骤操作:
     
         1) 展开服务器组。 
     
         2) 右键点击服务器,然后点击属性。 
     
         3) 在安全性选项卡的审核等级中,点击失败。  
       4) 要使这个设置生效,您必须停止并重新启动服务器。

  • 相关阅读:
    如何学习编程语言?
    spring AOP(1)
    一个老工程师给年轻工程师的十大忠告!!!
    跳楼时看到的[转]
    Python distribution打包&安装流程
    php rsa类的一个写法
    yii数据表关联操作
    JIRA是个好工具
    Yii CModel.rules() 方法 validate预定义完整列表
    Python Challenge挑战一下
  • 原文地址:https://www.cnblogs.com/BlogNetSpace/p/1346834.html
Copyright © 2011-2022 走看看