查询慢是和表结构,语句,系统等相关的 建索引等方法都可以改善表结构, 另外如果返回数据量很大,当然会慢,所以你尽量查询相对有用的数据 再就是查询语句了 比如用in查询没有jion查询快,还有 between 改成 > <会快 再还有,用子查询也会慢很多, 如果是一些很复杂的查询,可以改用存储过程会好点,有时用临时表会慢但,从海量数据中查询取数进行子查询又不如用临时表快,不同的问题用不同的解决方法,看你要哪种了,单看你的问题无法直接判断。 不过,优化查询句是关键的了。
❷ 从外到内提高SQL Server数据库性能
如何提高SQL Server数据库的性能 该从哪里入手呢?笔者认为 该遵循从外到内的顺序 来改善数据库的运行性能 如下图
第一层 网络环境
到企业碰到数据库反映速度比较慢时 首先想到的是是否是网络环境所造成的 而不是一开始就想着如何去提高数据库的性能 这是很多数据库管理员的一个误区 因为当网络环境比较恶劣时 你就算再怎么去改善数据库性能 也是枉然
如以前有个客户 向笔者反映数据库响应时间比较长 让笔者给他们一个提高数据库性能的解决方案 那时 笔者感到很奇怪 因为据笔者所知 这家客户数据库的记录量并不是很大 而且 他们配置的数据库服务器硬件很不错 笔者为此还特意跑到他们企业去查看问题的原因 一看原来是网络环境所造成的 这家企业的客户机有 多台 而且都是利用集线器进行连接 这就导致企业内部网络广播泛滥 网络拥塞 而且由于没有部署企业级的杀毒软件 网络内部客户机存在病毒 掠夺了一定的带宽 不仅数据库系统响应速度比较慢 而且其他应用软件 如邮箱系统 速度也不理想
在这种情况下 即使再花十倍 百倍力气去提升SQL Server数据库的性能 也是竹篮子打水一场空 因为现在数据册竖库服务器的性能瓶颈根本不在于数据库本身 而在于企业的网络环境 若网络环境没有得到有效改善 则SQL Server数据库性能是提高不上去的
为此 笔者建议这家企业 想跟他们的网络管理员谈谈 看看如何改善企业的网络环境 减少广播包和网络冲突;并且有效清除局域网内的病毒 木马等等 三个月后 我再去回访这家客户的时候 他们反映数据库性能有了很大的提高 而且其他应用软件 性能也有所改善
所以 当企业遇到数据库性能突然降低的时候 第一个反应就是查看网络环境 看看其实否有恶化 只有如此 才可以少走冤枉路
第二层 服务器配置
这里指的服务器配置 主要是讲数据库服务器的硬件配置以及周边配套 虽然说 提高数据库的硬件配置 需要企业付出一定的代价 但是 这往往是一个比较简便的方法 比起优化SQL语句来说 其要简单的多
如企业可以通过增加硬盘的数量来改善数据库的性能 在实际工作中 硬盘输入输出瓶颈经常被数据库管理员所忽视 其实 到并发访问比较多的时候 硬盘输入输出往往是数据库性能的一个主要瓶颈之一 此时 若数据库管理员可以增加几个硬盘 通过磁盘阵列来分散磁盘的压力 无疑是提高数据库性能的一个捷径
如增加服务器的内存或者CPU 当数据库管理员发现数据库性能的不理想是由内存或者CPU所造成的 此时 任何的改善数据库服务器本身的措施都将一物用处 所以 有些数据库管理专家 把改善服务器配置当作败姿乱数据库性能调整的一个先决条件
如解决部署在同一个数据库服务器上的资源争用问题 虽然我们多次强调 要为数据库专门部署一个服务器 但是 不少企业为了降低信息化的成本 往往把数据库服务器跟应用服务器放在同一个服务器中 这就会导致不同服务器之间的资源争用问题 如把文件服务器跟数据服务器部署在同一个服务器中 当对文件服务器进行备份时 数据库性能就会有明显的下降 所以 在数据库性能发现周期性的变化时 就要考虑是否因为服务器上不同应用对资源的争夺所造成的
故 笔者建察档议 改善数据库性能时第二个需要考虑的层面 就是要看看能否通过改善服务器的配置来实现
第三层 数据库服务器
当通过改善网络环境或者提高服务器配置 都无法达到改善数据库性能的目的时 接下去就需要考察数据库服务器本身了 首先 就需要考虑数据库服务器的配置
一方面 要考虑数据库服务器的连接模式 SQL Server数据库提供了很多的数据库模式 不同的数据库连接模式对应不同的应用 若数据库管理员能够熟悉企业自身的应用 并且选择合适的连接模式 这往往能够达到改善数据库性能的目的
其次 合理配置数据库服务器的相关作业 如出于安全的需要 数据库管理员往往需要对数据库进行备份 那么 备份的作业放在什么时候合适呢?当然 放在夜晚 夜深人静的时候 对数据库进行备份最好 另外 对于大型数据库 每天都进行完全备份将会是一件相当累人的事情 虽然累得不是我们 可是数据库服务器也会吃不消 差异备份跟完全备份结合将是改善数据库性能的一个不错的策略
第四层 数据库对象
若以上三个层面后 数据库性能还不能够得到大幅度改善的话 则就需要考虑是否能够调整数据库对象来完成我们的目的 虽然调整数据库对象往往可以提到不错的效果 但是 往往会对数据库产生比较大的影响 所以 笔者一般不建议用户一开始就通过调整数据库对象来达到改善数据库性能的目的
数据库对象有表 视图 索引 关键字等等 我们也可以通过对这些对象进行调整以实现改善数据库性能的目标
如在视图设计时 尽量把其显示的内容缩小 宁可多增加视图 如出货明细表 销售人员可能希望看到产品编号 产品中英文描述 产品名字 出货日期 客户编号 客户名字等等 但是 对于财务来说 可能就不需要这么全的信息 他们只需要产品编号 客户编号 出货日期等等少量的信息即可 所以 能可浪费一点代码的空间 设计两张视图 对应不同部门的需求 如此 财务部门在查询数据时 不会为不必要的数据浪费宝贵的资源
如可以通过合理设置索引来提高数据库的性能 索引对于提高数据的查询效率 有着非常好的效果 对一些需要重复查询的数据 或者数据修改不怎么多的表设置索引 无疑是一个不错的选择
另外 要慎用存储过程 虽然说存储过程可以帮助大家实现很多需求 但是 在万不得已的情况下 不要使用存储过程 而利用前台的应用程序来实现需求 这主要是因为在通常情况下 前台应用程序的执行效率往往比后台数据库存储过程要高的多
第五层 SQL 语句
若以上各个层面你都努力过 但是还不满足由此带来的效果的话 则还有最后一招 通过对SQL语句进行优化 也可以达到改善数据库性能的目的
虽然说SQL Server服务器自身就带有一个SQL语句优化器 他会对用户的SQL语句进行调整 优化 以达到一个比较好的执行效果 但是 据笔者的了解 这个最多只能够优化一些粗略的层面 或者说 %的优化仍然需要数据库管理员的配合 要数据库管理员跟SQL优化器进行配合 才能够起到非常明显的作用
不过 SQL语句的调整对于普通数据库管理员来说 可能有一定的难度 除非受过专业的训练 一般很难对SQL语句进行优化 还好笔者受过这方面的专业训练 对这方面有比较深的认识 如在SQL语句中避免使用直接量 任何一个包含有直接量的SQL语句都不太可能被再次使用 我们数据库管理员要学会利用主机变量来代替直接量 不然 这些不可再用的查询语句将使得程序缓存被不可再用的SQL语句填满 这都是平时工作中的一些小习惯
lishixin/Article/program/SQLServer/201311/22452
❸ 数据库MSSQL运行慢是什么原因
(1) 可以考虑一下索引的问题
对在你的SQL语句中WHERE子句里涉及的列, 设置为索引列, 将极大提高你的访问性能. 特别是频繁访问的表,更应该注意这个问题.
(2) 考虑存储过程的使用
对经常访问或连续操作的SQL语句,可以考虑放在存储过程中处理, 由于存储过程是预编译的, 一般可以提高速度
(3) 考虑"事务"的问题
事务中的SQL语句,在提交前会锁定相关的表,使其无法访问,直到提交为止
(4) 考虑你的连接方式, 是否用到了连接池, 一般连接池的合理使用会提高你的速度及程序的可用性.
❹ sqlserver 数据库服务突然缓慢 重启后正常 运行的sql只有30多条
没有用到索引或者就是内存小了,因为没有备份运行时有的sql丢失了。
看看数据库内存设置是否比较小,数据库表是否建立合理的索引。
因为主机长期在工作.数据会一上在增多..对于内存还有CPU来说不是所有数据都可以一次性的完全处理好。就会有一些"尾数"包括记录,然而越来越多,会让主机运行速度变慢。如果用好点的专用的服务器硬盘,内存会让主机更长时间的不用重启。所以SQL还是要用高一点的配置。
❺ 如何解决SQL Server数据库查询速度慢
�纬闪似烤毙вΑ� 3、没有创建计算列导致查询不优化。 4、内存不足5、网络速度慢6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8、sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。 9、返回了不必要的行和列10、查询语句不好,没有优化 可以通过以下方法来优化查询 : 1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要。 2、纵向、横向分割表,减少表的尺寸(sp_spaceuse) 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自动评估选择的。单个任务分解成多个任务,就可以在处理器上运行。例如耽搁查询 的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作UPDATE,INSERT, DELETE还不能并行处理。 8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like ''a%'' 使用索引 like ''%a'' 不使用索引用 like ''%a%'' 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR.对于字段的值很长的建全文索引。 9、DB Server 和APPLication Server 分离;OLTP和OLAP分离 10、分布式分区视图可用于实现数据库服务器联合体。 联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据库服务器联合体的机制能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,参见设计联合数据库服务器。(参照SQL帮助文件''分区视图'') a、在实现分区视图之前,必须先水平分区表 b、在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务器上 运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的。 11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE. 设置自动收缩日志。对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。 在T-sql的写法上有很大的讲究,下面列出常见的要点:首先,DBMS处理查询计划的过程是这样的: 1、 查询语句的词法、语法检查2、 将语句提交给DBMS的查询优化器3、 优化器做代数优化和存取路径的优化4、 由预编译模块生成查询规划5、 然后在合适的时间提交给系统处理执行6、 最后将执行结果返回给用户。 其次,看一下SQL SERVER的数据存放的结构:一个页面的大小为8K(8060)字节,8个页面为一个盘区,按照B树存放。 12、 Commit和rollback的区别 Rollback:回滚所有的事物。 Commit:提交当前的事物。 没有必要在动态SQL里写事物,如果要写请写在外面如: begin tran exec(@s) commit trans 或者将动态SQL 写成函数或者存储过程。 13、在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。 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 语句中的锁提示。锁提示 只读乐观数值 指定NOLOCK 提示将使指定了该提示的表在游标内是只读的。 16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引 17、注意UNion和UNion all 的区别。UNION all好 18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的 19、查询时不要返回不需要的行、列 20、 用sp_configure ''query governor cost limit''或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。 SET LOCKTIME设置锁的时间 21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行 22、 在SQL2000以前,一般不要用如下的字句: "IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE ''%500''",因为他们不走索引全是表扫描。也不要在WHere字句中的列名加函数,如Convert,substring等,如果必须用函数的时 候,创建计算列再创建索引来替代。还可以变通写法:WHERE SUBSTRING(firstname,1,1) = ''m''改为WHERE firstname like ''m%''(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。NOT IN会多次扫描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作。如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同 的是IS NULL,“NOT", "NOT EXISTS", "NOT IN"能优化她,而”<>“等还是不能优化,用不到索引。 23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL.一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。 24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN (‘男’,‘女’) 25、将需要查询的结果预先计算好放在表中,查询的时候再SELECT.这在SQL7.0以前是最重要的手段。例如医院的住院费计算。 26、MIN() 和 MAX()能使用到合适的索引。 27、 数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束),Procere.这样不仅维护工作小,编写程 序质量高,并且执行的速度快。 28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌INsert来插入(不知JAVA 是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值。
❻ 如何解决SQL Server查询速度缓慢的问题
优化SQL Server查询速度的方法:
1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要.
2、纵向、横向分割表,减少表的尺寸(sp_spaceuse)
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自动评估选择的。单个任务分解成多个任务,就可以在处理器上运行。例如耽搁查询的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作UPDATE,INSERT, DELETE还不能并行处理。
8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like ''a%'' 使用索引 like ''%a'' 不使用索引用 like ''%a%'' 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。
9、DB Server 和APPLication Server 分离;OLTP和OLAP分离
10、分布式分区视图可用于实现数据库服务器联合体。
联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据库服务器联合体的机制能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,参见设计联合数据库服务器。(参照SQL帮助文件''分区视图'')
a、在实现分区视图之前,必须先水平分区表
b、在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务器上运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的。
11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE.设置自动收缩日志.对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。
在T-sql的写法上有很大的讲究,下面列出常见的要点:首先,DBMS处理查询计划的过程是这样的:
1、查询语句的词法、语法检查
2、将语句提交给DBMS的查询优化器
3、优化器做代数优化和存取路径的优化
4、由预编译模块生成查询规划
5、然后在合适的时间提交给系统处理执行
6、最后将执行结果返回给用户。
其次,看一下SQL SERVER的数据存放的结构:一个页面的大小为8K(8060)字节,8个页面为一个盘区,按照B树存放。
12、 Commit和rollback的区别 Rollback:回滚所有的事物。 Commit:提交当前的事物.没有必要在动态SQL里写事物,如果要写请写在外面如: begin tran exec(@s) commit trans 或者将动态SQL 写成函数或者存储过程。
13、在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。
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 语句中的锁提示。
16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引
17、注意UNion和UNion all 的区别。UNION all好
18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的
19、查询时不要返回不需要的行、列
20、用sp_configure ''query governor cost limit''或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。 SET LOCKTIME设置锁的时间
21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行
22、在SQL2000以前,一般不要用如下的字句
", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE ''%500''",因为他们不走索引全是表扫描。也不要在WHere字句中的列名加函数,如Convert,substring等,如果必须用函数的时候,创建计算列再创建索引来替代.还可以变通写法:WHERE SUBSTRING(firstname,1,1)= ''m''改为WHERE firstname like ''m%''(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。NOT IN会多次扫描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同的是IS NULL,“NOT", "NOT EXISTS", "NOT IN"能优化她,而”<>”等还是不能优化,用不到索引。
23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。
24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN (‘男’,‘女’)
25、将需要查询的结果预先计算好放在表中,查询的时候再SELECT。这在SQL7.0以前是最重要的手段。例如医院的住院费计算。
26、MIN()和 MAX()能使用到合适的索引。
27、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束),Procere.这样不仅维护工作小,编写程序质量高,并且执行的速度快。
28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌INsert来插入(不知JAVA 是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值.存储过程就没有这些动作:方法:Create procere p_insert as insert into table(Fimage) values (@image),在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。
❼ 当数据库变慢时的解决方法有哪些
我们使用电脑和手机时候最不能忍受就是设备又卡又慢了,严重影响我们工作或者游戏体验。当数据库变慢时,我们应如何入手,下面的解决方法。
方法步骤
第一章 检查系统的状态
1.1 使用sar来检查操作系统是否存在IO问题
1.2 关注内存vmstat
1.3 找到使用资源特别大的Oracle的session及其执行的语句
1.4 查找前十条性能差的sql语句
当数据库变慢时,我们应如何入手
当应用管理员通告现在应用很慢、数据库很慢时,当Oracle DBA在数据库上做几个示例的Select也发现同样的问题时,有些时侯就会无从下手,因为DBA认为数据库的各种命种率都是满足Oracle文档的建议。实际上如今的优化己经向优化等待(waits)转型了,实际中性能优化最根本的出现点也都集中在I/O,这是影响性能最主要的方面,由系统中的等待去发现Oracle库中的不足、操作系统某些资源利用的不合理是一个比较好的办法。下面把一些实践经验与大家分享,本文测重于Unix环境。
第一章 检查系统的状态
通过操作系统的一些工具检查系统的状态,比如CPU、内存、交换、磁盘的利用率,根据经验或与系统正常时的状态相比对,有时系统表面上看起来看空闲,这也可能不是一个正常的状态,因为cpu可能正等待IO的完成。除此之外,还应观注那些占用系统资源(cpu、内存)的进程。
1.1 使用sar来检查操作系统是否存在IO问题
#sar -u 2 10 -- 即每隔2秒检察一次,共执行20次。
结果示例:
注:在redhat下,%system就是所谓的%wio。
Linux 2.4.21-20.ELsmp (YY075) 05/19/2005
10:36:07 AM CPU %user %nice %system %idle
10:36:09 AM all 0.00 0.00 0.13 99.87
10:36:11 AM all 0.00 0.00 0.00 100.00
10:36:13 AM all 0.25 0.00 0.25 99.49
10:36:15 AM all 0.13 0.00 0.13 99.75
10:36:17 AM all 0.00 0.00 0.00 100.00
其中:
Ø %usr指的是用户进程使用的cpu资源的百分比;
Ø %sys指的是系统资源使用cpu资源的百分比;
Ø %wio指的是等待io完成的百分比,这是值得观注的一项;
Ø %idle即空闲的百分比。
如果wio列的值很大,如在35%以上,说明系统的IO存在瓶颈,CPU花费了很大的时间去等待I/O的完成。Idle很小说明系统CPU很忙。像以上的示例,可以看到wio平均值为11,说明I/O没什么特别的问题,而idle值为零,说明cpu已经满负荷运行了。
当系统存在IO问题时,可以从以下几个方面解决:
Ø 联系相应的操作系统的技术支持对这方面进行优化,比如hp-ux在划定卷组时的条带化等方面。
Ø 查找Oracle中不合理的sql语句,对其进行优化;
Ø 对Oracle中访问量频繁的表除合理建索引外,再就是把这些表分表空间存放以免访问上产生热点,再有就是对表合理分区。
1.2 关注内存
常用的工具便是vmstat,对于hp-unix来说,可以用glance。Aix来说可以用topas。当发现vmstat中pi列非零,memory中的free列的值很小,glance、topas中内存的利用率多于80%时,这时说明内存方面应该调节一下。方法大体有以下几项:
Ø 划给Oracle使用的内存不要超过系统内存的1/2,一般保在系统内存的40%为益。
Ø 为系统增加内存;
Ø 如果你的连接特别多,可以使用MTS的方式;
Ø 打全补丁,防止内存漏洞。
1.3 找到使用资源特别大的Oracle的session及其执行的语句
Hp-unix可以用glance或top。IBM AIX可以用topas。此外可以使用ps的命令。
通过这些程序可以找到点用系统资源特别大的这些进程的进程号,就可以通过以下的sql语句发现这个pid正在执行哪个sql,这个sql最好在pl/sql developer、toad等软件中执行:
SELECT a.username, a.machine, a.program, a.sid, a.serial#, a.status,
c.piece, c.sql_text
FROM v$session a, v$process b, v$sqltext c
WHERE b.spid = 'ORCL'
AND b.addr = a.paddr
AND a.sql_address = c.address(+)
ORDER BY c.piece;
可以把得到的这个sql分析一下,看一下它的执行计划是否走索引。对其优化避免全表扫描,以减少IO等待,从而加快语句的执行速度。
提示:在做优化sql时,经常碰到使用in的语句,这时一定要用exists把它给换掉,因为Oracle在处理In时是按Or的方式做的,即使使用了索引也会很慢。比如:
SELECT col1, col2, col3 FROM table1 a
WHERE a.col1 NOT IN (SELECT col1 FROM table2)
可以换成:
SELECT col1, col2, col3 FROM table1 a
WHERE NOT EXISTS
(SELECT 'x' FROM table2 b WHERE a.col1=b.col1)
1.4 查找前十条性能差的sql语句
SELECT * FROM (SELECT parsing_user_id, executions, sorts, command_type,
disk_reads, sql_text FROM v$sqlarea
ORDER BY disk_reads DESC)
WHERE ROWNUM<10;
第二章 检查会话状态
要快速发现Oracle Server的性能问题的原因,可以求助于v$session_wait视图,看系统的这些session在等什么,使用了多少的IO。以下是参考脚本:
-- 脚本说明:查看占I/O较大的正在运行的session:
SELECT se.sid, se.serial#, pr.spid, se.username, se.status, se.terminal,
se.program, se.mole, se.sql_address, st.event, st.p1text,
si.physical_reads, si.block_changes
FROM v$session se, v$session_wait st, v$sess_io si, v$process pr
WHERE st.sid=se.sid AND st.sid=si.sid
AND se.PADDR=pr.ADDR
AND se.sid>6
AND st.wait_time=0
AND st.event NOT LIKE '%SQL%'
ORDER BY physical_reads DESC;
对检索出的结果的几点说明:
1. 以上是按每个正在等待的session已经发生的物理读排的序,因为它与实际的I/O相关。
2. 可以看一下这些等待的进程都在忙什么,语句是否合理?
SELECT sql_address FROM v$session WHERE sid=;
SELECT * FROM v$sqltext WHERE address=;
执行以上两个语句便可以得到这个session的语句。
也以用alter system kill session 'sid, serial#';把这个session杀掉。
3. 应观注一下event列,这是调优的关键一列,下面对常出现的event做以简要的说明:
1) buffer busy waits,free buffer waits这两个参数所标识是dbwr是否够用的问题,与IO很大相关的,当v$session_wait中的free buffer wait的条目很小或没有时,说明系统的dbwr进程决对够用,不用调整;free buffer wait的条目很多,系统感觉起来一定很慢,这时说明dbwr已经不够用了,它产生的wio已经成为数据库性能的瓶颈,这时的解决办法如下:
Ø 增加写进程,同时要调整db_block_lru_latches参数:
示例:修改或添加如下两个参数
db_writer_processes=4
db_block_lru_latches=8
Ø 开异步IO。IBM这方面简单得多,hp则麻烦一些,可以与Hp工程师联系。
2) db file sequential read,指的是顺序读,即全表扫描,这也是应尽量减少的部分,解决方法就是使用索引、sql调优,同时可以增大db_file_multiblock_read_count这个参数。
3) db file scattered read参数指的是通过索引来读取,同样可以通过增加db_file_multiblock_read_count这个参数来提高性能。
4) latch free与栓相关,需要专门调节。
5) 其他参数可以不特别观注
补充:解决系统变慢的常用技巧方法
1、在我的电脑窗口,右击要清理的盘符―“属性”―“清理磁盘”--勾选要删除的文件--确定--是。
2、右键浏览器e――属性――点2个删除1个清除(都要逐一确定)――确定 。
3、把C:WINDOWSPrefetch(预读文件)把里面的文件全部删除
4、用优化大师或超级兔子清理注册表和垃圾文件。
5、“开始”――运行中输入msconfig――确定――启动――除了输入法ctfmon以外的勾全去掉。
6、右键我的电脑”――属性――点高级――点启动和故障恢复中的设置――去掉所有的勾――写入调试信息选择“无”――确定――点高级下面错误报告――点禁用――2次确定。
7、“开始”..打开控制面板中的文件夹选项..点查看..点去末项自动搜索文件夹前面的勾..确定。
8、右键我的电脑――属性――硬件――设备管理器――双击IDE控制器――次要通道――高级设置――传送模式都选DMA――设备类型选无――确定――主要通道也同样设置――确定。
9、右键C盘进行磁盘清理和其它选项中的系统还原清理。
❽ sql数据库文件过大,程序运行非常慢,怎么办
收缩数据库
一般情况下,SQL数据库的收缩并不能很大程度上减小数据库大小,其主要作用是收缩日志大小,应当定期进行此操作以免数据库日志过大
1、设置数据库模式为简单模式:打开SQL企业管理器,在控制台根目录中依次点开Microsoft SQL Server-->SQL Server组-->双击打开你的服务器-->双击打开数据库目录-->选择你的数据库名称(如论坛数据库Forum)-->然后点击右键选择属性-->选择选项-->在故障还原的模式中选择“简单”,然后按确定保存
2、在当前数据库上点右键,看所有任务中的收缩数据库,一般里面的默认设置不用调整,直接点确定
3、收缩数据库完成后,建议将您的数据库属性重新设置为标准模式,操作方法同第一点,因为日志在一些异常情况下往往是恢复数据库的重要依据
❾ oracle数据库运行sql很卡很慢很顿,看等待事件都是cursor:pin s on x,这是啥
详解cursor: pin S wait on X等待事件 ‘cursor: pin * events’等待事件 该类等待事件一般是为了pin相关的子游标 ‘Cursor: pin S on X’ 最常见的等待事件, 进程为了共享操作例如执行pin游标而以SHRD S mode申请mutex, 但是未立即获得。原因是该游标被其他进程以EXCL X mode 持有了。 实际该 cursor: pin S wait on X等待事件往往是由于其他因素诱发的。Mutex争用仅仅是问题的症状,但根本原因需要Database Consultant 进一步挖掘。 下面我们列出一些已知的常见案例, 在这些例子中可以看到 我上面提到的 Mutex的争用仅仅是伪争用: 过多的子游标 High Version Counts 过多的子游标版本Version Count可能导致Mutex 争用,一般一个SQL的Version Count不要高于500。 检查High Version Count很简单, 在AWR里就有SQL ordered by High Version Count,也可以写SQL查V$SQL、V$SQLAREA 昂贵的X$、V$视图查询 一些对于V$、X$视图的查询,需要访问X$KGL*之类的fixed table,可能触发Mutex争用。 Mutex持有者得不到CPU Mutex持有者若得不到足够的CPU片可能一直阻塞他人,直到它拿到需要的CPU。 这种情况可能由于OS操作系统的实际情况或者使用Resource Manager而引起。需要配合AWR中的Host CPU、Instance CPu一起看。 已经被KILLED的SESSION仍持有Mutex 当session正持有Mutex,而其对应的Process被强制KILL掉, 则直到PMON彻底清理掉该Dead Process并释放Mutex,其他session才能不再等待。 诊断该类问题,最好能检查PMON的TRACE。 当然也存在部分BUG会导致PMON清理过程非常慢。 举例来说,bug 9312879描述了一种场景:PMON 需要获得某个Mutex以便清理某个dead process,但是该Mutex又被其他进程持有,则PMON甚至无法开始真正清理并释放Mutex。 如果自己搞不定可以找ASKMACLEAN专业ORACLE优化团队成员帮您搞定!