如何做SqlServer 数据查询优化!

作者&投稿:雷朗 (若有异议请与网页底部的电邮联系)
数据库的多表大数据查询应如何优化?~

1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0
2.应尽量避免在 where 子句中使用!=或操作符,否则将引擎放弃使用索引而进行全表扫描。优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。
3.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
4.in 和 not in 也要慎用,因为IN会使系统无法使用索引,而只能直接搜索表中的数据。如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
5.尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。
见如下例子:
SELECT * FROM T1 WHERE NAME LIKE ‘%L%’
SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’
SELECT * FROM T1 WHERE NAME LIKE ‘L%’
即使NAME字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作。
6.必要时强制查询优化器使用某个索引,如在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
select id from t where num=@num
可以改为强制查询使用索引:
select id from t with(index(索引名)) where num=@num
7.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
SELECT * FROM T1 WHERE F1/2=100
应改为:
SELECT * FROM T1 WHERE F1=100*2
SELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=’5378’
应改为:
SELECT * FROM RECORD WHERE CARD_NO LIKE ‘5378%’
SELECT member_number, first_name, last_name FROM members
WHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21
应改为:
SELECT member_number, first_name, last_name FROM members
WHERE dateofbirth < DATEADD(yy,-21,GETDATE())
即:任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。
8.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id
应改为:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
9.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
10.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
11.很多时候用 exists是一个好的选择:
elect num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)
SELECT SUM(T1.C1)FROM T1 WHERE(
(SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0)
SELECT SUM(T1.C1) FROM T1WHERE EXISTS(
SELECT * FROM T2 WHERE T2.C2=T1.C2)
两者产生相同的结果,但是后者的效率显然要高于前者。因为后者不会产生大量锁定的表扫描或是索引扫描。

SQL Server数据库查询速度慢的原因有很多,常见的有以下几种:
1、没有索引或者没有用到索引(这是查询慢最常见的问题,是数据库设计的缺陷)
2、I/O吞吐量小,形成了瓶颈效应。
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)。索引应该尽量小,使用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段。

一、建立索引
二、建立存储过程
三、只查询您所需要的数据,不要把所有数据都查询出来,防止数据冗余。
四、对于大量及海量数据一般还要建立分区

有很多种优化,索引\分区是常用优化方法。

1、适当的建立索引
2、规范查询语句
3、sql语句中尽量用参数,以便使用计划
4、拆分表,表分区

影响查询效率的因素    
SQLServer处理查询计划的过程是这样的:在做完查询语句的词法、语法检查之后,将语句提交给SQLServer的查询优化器,查询优化器通过检查索引的存在性、有效性和基于列的统计数据来决定如何处理扫描、检索和连接,并生成若干执行计划,然后通过分析执行开销来评估每个执行计划,从中选出开销最小的执行计划,由预编译模块对语句进行处理并生成查询规划,然后在合适的时间提交给系统处理执行,最后将执行结果返回给用户。所以,SQLServer中影响查询效率的因素主要有以下几种:
  1.没有索引或者没有用到索引。索引是数据库中重要的数据结构,使用索引的目的是避免全表扫描,减少磁盘I/O,以加快查询速度。
  2.没有创建计算列导致查询不优化。
  3.查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)。
  4.返回了不必要的行和列。
  5.查询语句不好,没有优化。其中包括:查询条件中操作符使用是否得当;查询条件中的数据类型是否兼容;对多个 表查询时,数据表的次序是否合理;多个选择条件查询时,选择条件的次序是否合理;是否合理安排联接选择运算等。

SQLServer数据查询优化方法
    3.1建立合适的索引  索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。当根据索引码的值搜索数据时,索引提供了对数据的快速访问。事实上,没有索引,数据库也能根据SELECT语句成功地检索到结果,但随着表变得越来越大,使用“适当”的索引的效果就越来越明显。索引的使用要恰到好处,其使用原则有:
  (1)对于基本表,不宜建立过多的索引;
  (2)对于那些查询频度高,实时性要求高的数据一定要建立索引,而对于其他的数据不考虑建立索引;
  (3)在经常进行连接,但是没有指定为外键的列上建立索引;
  (4)在频繁进行排序或分组(即进行groupby或 orderby操作)的列上建立索引;
  (5)在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度;
  (6)如果待排序的列有多个,可以在这些列上建立复合索引。  在SQLServer中,索引按索引表达式包含的列分为单列索引和复合索引。检查查询语句的where子句,因为这是优化器重要关注的地方。包含在where里面的每一列都是可能的侯选索引,为能达到最优的性能,例如:对于在where子句中给出了 column1这个列,下面的两个条件可以提高索引的优化查询性能!
第一:在表中的column1列上有一个单索引;
第二:在表中有多索引,但是 column1是第一个索引的列。避免定义多索引而column1是第二个或后面的索引,这样的索引不能优化服务器性能。例如:下面的例子用了pubs数据库。  SELECTau_id,au_lname,au_fname  FROMauthorsWHEREau_lname=’White’  按下面几个列上建立的索引将会是对优化器有用的索引  au_lname  au_lname,au_fname  而在下面几个列上建立的索引将不会对优化器起到好的作用  au_address  au_fname,au_lname  在SQLServer中,索引按存储结构分为聚簇索引和非聚簇索引。聚簇索引是按照定义数据列值的顺序在物理上对记录排序,在一个表上只能有一个聚簇索引,聚簇索引查询速度较快,但缺点是对表进行修改操作时速度较慢,因为为了保证表中记录的物理顺序与索引的顺序一致,必须将记录插入到数据页的相应位置,从而数据页中的数据必须重排。在下面的几个情况下,可以考虑用聚簇索引:
(1)某列包括的不同值的个数是有限的(但是不是极少的)。如顾客表的州名列有50个左右的不同州名的缩写值,可以使用聚簇索引。  
(2)对返回一定范围内值的列可以使用聚簇索引,如用between,>,>=,   Select*fromsaleswhereord_datebetween’5/1/93’and’6/1/93’  
(3)对查询时返回大量结果的列可以使用聚簇索引。  SELECT*FROMphonebookWHERElast_name=’Smith’  当有大量的行正在被插入表中时,要避免在本表一个自然增长(例如,identity列)的列上建立聚簇索引。如果你建立了聚簇的索引,那么insert的性能就会大大降低。因为每一个插入的行必须到表的最后,表的最后一个数据页。
  非聚簇索引指定表中的逻辑顺序,一个表上可以建立多达249个非聚簇索引,它查询的速度比不建立索引快,但比聚簇索引慢,插入数据比聚簇索引快,因为纪录直接被追加到数据末尾。可以在以下情况下考虑使用非聚簇索引。
(1)在有很多不同值的列上可以考虑使用非聚簇索引,如employee表中的emp_id列可以建立非聚簇索引。
(2)查询结果集返回的是少量或单行的结果集。例如  
select*fromemployeewhereemp_id=’pcm9809f’  
(3)查询语句中orderby子句的列上可以考虑使用非聚簇索引。

    3.2常用的计算字段(如总计、最大值等)可以考虑存储到数据库实体中。  例如仓库管理系统中有材料入库表,其字段为:材料编号、材料名称、型号,单价,数量…,而金额是用户经常需要在查询和报表中用到的,在表的记录量很大时,有必要把金额作为一个独立的字段加入到表中。这里可以采用触发器以在客户端保持数据的一致性。

    3.3用where子句来限制必须处理的行数。  在执行一个查询时,用一个where子句来限制必须处理的行数,除非完全需要,否则应该避免在一个表中无限制地读并处理所有的行。例如:  |||   select qty from sales where stor_id=’7131’是很有效的,比无限制的查询selectqtyfromsales有效,避免给客户的最后数据选择返回大量的结果集。当然也可以用TOP限制返回结果集的行数。

    3.4尽量使用数字型字段。  一部分开发人员和数据库管理人员喜欢把包含数值信息的字段设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

    3.5查询语句的优化。  对于一条复杂的查询语句来说,对相同查询条件的实现一般总可以有多种不同的表达方法,而不同的表达会使数据库的响应速度大相径庭。据统计,约有80%以上的性能问题是由于使用了不恰当的查询语句造成的,因此SQL语句的质量对整个系统效率有重大关系。
下面介绍查询语句优化方面的一些技巧:
(1)避免使用不兼容的数据类型。例如float和int、char和varchar、 binary和varbinary是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如:   SELECTnameFROMemployeeWHEREsalary>60000  在这条语句中,如salary字段是money型的,则优化器很难对其进行优化,因为60000是个整型数。这条语句可以改为:  SELECTnameFROMemployeeWHEREsalary>$60000
  (2)尽量避免在Where条件里使用非聚合表达式,因为非聚合表达式很难利用到索引,通常SQLServer不得不进行大规模的扫描。像!=或<>、 ISNULL或ISNOTNULL、IN,NOTIN等这样的操作符构成的表达式都是非聚合表达式。非聚合表达式会导致查询效率大大降低。例如:   SELECTidFROMemployeeWHEREid!='B%'  优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。
   (3)尽量避免在WHERE子句中对字段进行函数或表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:  
SELECT*FROMemployeeWHEREsalary/2=100应改为: 
SELECT*FROMemployeeWHEREsalary=100*2   SELECT*FROMemployeeWHERESUBSTRING(emp_id,1,3)=’PCM’应改为:
SELECT*FROMemployeeWHEREemp_idLIKE‘5378%’   SELECTmember_number,first_name,last_nameFROMmembers   WHEREDATEDIFF(yy,datofbirth,GETDATE())>21应改为:
SELECT member_number,first_name,last_name FROM members WHERE dateofbirth  即:任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。
(4)避免使用LEFTJOIN   SQL的一个有价值的常用功能是LEFTJOIN。它可以用于检索第一个表中的所有行、第二个表中所有匹配的行、以及第二个表中与第一个表中不匹配的所有行。例如,如果希望返回每个客户及其定单,使用LEFTJOIN则可以显示有定单和没有定单的客户。LEFTJOIN消耗的资源非常之多,因为它们包含与 NULL(不存在)数据匹配的数据。因此在构造查询语句时尽量避免使用LEFTJOIN。
(5)尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。  见如下例子:  
SELECT*FROMmembersWHEREfirst_nameLIKE‘%MA%’   SELECT*FROMmembersWHERESUBSTING(first_name,3,1)=’MA’   SELECT*FROMmembersWHEREfirst_nameLIKE‘MA%’  即使NAME字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作。(6)避免相关子查询  一个列的标签同时在主查询和 WHERE子句中的查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此应当尽量避免子查询。可 以采用子查询“展平”技术,将子查询转变为连接,半连接或反连接,从而达到优化查询的目的。例如查询找出有工资超过10000的职工所在的部门名称。   SELECT部门名FROM部门WHERE部门号IN  (SELECT部门号FROM职工WHERE工资>10000)  此查询将扫描部门表的 每一行查找所有满足子查询条件的职工记录。可以将部门表作为连接的内表,在这种情况下,查询作为通常的连接来执行,首先对职工表进行唯一的部门号筛选,以 消除冗余的部门号,转化后的语句为:  SELECTB.部门名FROM(SELECTDISTINCT部门号FROM职工WHERE工 资>10000,部门DWHEREB.部门号=D.部门号  对于SQL语句的优化方法还有很多,在这里就不一一例举了。

索引,重新写SQL。


如何让SQL Server数据库自动备份并压缩
从sqlserv2008开始备份都有自动压缩功能,不需要再额外压缩。可以在实例的属性中查看是否有开启压缩备份。自动备份只需要加任务计划选择定时执行就可以了。两项用自带的功能就完全能够实现

SQL SERVER2012同步Oracle数据
首先,这个需求是跨库跨平台的,一般sqlserver都装在win上,而oracle都装在linux上(当然,也有linux版的sqlserver,oracle也能装在win上,但是实现的方法和结果是一样的),但是对于ogg来讲无所谓,ogg的特点就是可以跨库跨平台跨版本来同步数据。源端是oracle,目标端是sqlserver,可以使用11版本的ogg来...

SQLSERVER 2000下载
是一款针对SQLServer7.0或SQLServer2000的存储过程、视图、触发器和函数进行加密和解 www.onlinedown.net\/soft\/30383.htm 9. WebICQ即时聊天工具 3.0 是一个Web聊天工具.安装说明:1、安装数据库,本系统使用SQLServer2000,请打开SQLServ www.onlinedown.net\/soft\/31476.htm 10. 铝加工(铝型材)...

为什么VIA启动了sqlserver服务就启动不了?
sqlserv 2005 和VIA冲突是因为共用端口导致的,你之前把“VIA协议”给启用了,停用“VIA协议”可以解决,"VIA协议"停用方法:开始->程序->Microsoft SQL Server 2005->配置工具->SQL Server Configuration Manager ->打开后找到"SQL Server 2005 网络配置"->MSSQLSERVER 属性的协议 在右边的属性...

用友通10.2软件要输入SQL servdr口令,说已被更改,要怎么安装数据库才能...
--用友通10.2软件要输入SQL servdr口令 --用友通如默认安装MSDE,直接命令行:rem 开始 -> 运行 -> 输入cmd,输入命令:osql -E rem 然后直接输入 exec master..sp_password null,'password','sa'go --OK,

使用SQL Server 2000的查询分析器时运行缓慢,请问如何解决?
• Microsoft SQL Server 2000 Workgroup Edition • Microsoft SQL Server 2000 Desktop Engine (Windows)• Microsoft SQL Server 2000 64-bit Edition 回到顶端 关键字: kbhotfixserver kbqfe kbqfe kbfix kbbug kbsqlserv2000presp4fix KB818095 KbMtzh kbmt 回到顶端 Microsof...

我删了所有数据库文件和日志后为什么启动不了SQL Server(MSSQL...
可以在企业管理器立面尝试恢复数据库,或者另行注册一个数据库,不行就没有办法了!

sqlservse求出表里a的字段1,和另一个表b的字段1求出他俩一共有多少相 ...
select count(1) from a inner join b on a.字段1=b.字段1

看公司给的项目,一运行就报com.microsoft.sqlserver.jdbc.SQLServerExcept...
你在SQL Server Management Studio里面新建连接,然后登陆的时候用sa用户登陆试试,你说没有用sa还是出现sa登陆失败可能是程序里面写死的,可以跟开发工程师联系一下

SQL安装出现这样的提示,安装不上.高手请帮忙啊!!!
1.卸载SQL Server2000 2.删除安装路径下所有文件 3.我的电脑,点右键,属性,计算机名,更改,把计算机名称改为大写(关键,全部字母都需要大写)4.重启电脑后再安装SQL Server 2000 有些电脑需要计算机名称为大写

道县15089534190: 如何根据sql数据库表中数据进行查询 -
空陈参蛇: sql server 查询一个表的所有信息:查询语法为:select * from 表名 语法中的”*“代表所有. 实际操作举例:某数据中有一表叫”user_user“,表中存储了一些用户信息; 1、查询”user_user“表中所有人员信息且所有字段,sql语句:select * ...

道县15089534190: sql server 怎么查询 -
空陈参蛇: 一般情况下: 1、人们不会直接操作SQL Server进行数据的管理和查询,只有管理、设计人员或是学习编程的朋友才会在SQL Server自带的管理器里进行数据的管理和查询工作. 2、设计好了的带SQL Server查询的应用(或叫程序)会有相对简...

道县15089534190: 如何使用SqlServer查询数据库表所有或指定记录 -
空陈参蛇: 首先需要登录打开 Sql Server先展开你需要查询的表,了解其中的字段名后点击新建查询查询中输入如下命令,系统会有实时提示正确后,点击执行如果表中没有数据则0显示查询中输入如下命令: select top 20 UserID,UserName from ReportServer$SQLSERVER.dbo.Users即可查看所有符合条件的记录. 注:其中 top 20 为最先的20条.可以去掉后显示所有. UserID,UserName 为指定字段名,如替换为 * 则显示所有字段. ReportServer$SQLSERVER.dbo.Users,分别为库名,表名.

道县15089534190: 在数据库中如何运用sql语句进行查询 -
空陈参蛇: 查询语句这些都是基础的数据库语法,可以查询相关的资料进行参考. 语句为:select * from 表名; 解析:从表里查询字段的内容~

道县15089534190: 如何使用SQL语言对数据库中的数据进行查询? -
空陈参蛇: select * form [表名];//查询表中所有数据 select [字段名] form [表名]; //查询表中指定字段的数据

道县15089534190: 如何在sql server2003中查询数据 -
空陈参蛇: 1.select * from 表名2.select * from 表名 where 查询字段 = 条件 如:查询30 岁以上的员工.select * from yuangongbiao where age > 30 yuangongbiao是你数据库中的员工表的名.

道县15089534190: 如何用SQL语句查询Excel数据 -
空陈参蛇: SELECT * FROM OpenDataSource( 'Microsoft.ACE.OLEDB.12.0', 'Data Source="c:\book1.xlsx";User ID=Admin;Password=;Extended properties=Excel 12.0')...[Sheet1$] SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0','Excel ...

道县15089534190: sql server 2008 数据库表是怎样查询数据的 -
空陈参蛇: 可以在SQL Server Management Studio里新建一个数据库关系图,将要查看的表添加到关系图里,主外键关系就能很清晰的显示出来了.数据库关系图在每个数据库的“数据库关系图”节点创建.

道县15089534190: .net怎么查询SQL Server数据库 -
空陈参蛇: 需要使用ADO.NET来对数据进行查询1.指定数据连接,不同的数据驱动,连接字符串不同SqlConnection con=new SqlConnection("server=.;database=数据库名称;uid=数据库用户名;pwd=数据库密码");2.指定SQL查询语句string sql="...

道县15089534190: 怎样从简单数据库用sql语句查询数据 -
空陈参蛇: 查询是SQL语言的核心,SQL语言只提供唯一一个用于数据库查询的语句,即SELECT语句.用于表达SQL查询的SELECT语句是功能最强也是最复杂的SQL语句,它提供了很多选项和使用方法.SELECT语句的命令格式如下:...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网