08r2系统服务器开索引,SQLSERVER2008R2正确使用索引
发布日期:2021-10-31 15:52:53 浏览次数:3 分类:技术文章

本文共 4949 字,大约阅读时间需要 16 分钟。

T1表 10000000万条数据,(插入时间36分钟,count(*)查询19秒,空间占用670M左右)sql

1.真正充分的利用索引

好比like '张%' 就是符合SARG(符合扫描参数)标准

而like '%张' 就不符合该标准数据库

通配符%在字符串首字符的使用会致使索引没法使用,虽然实际应用中很难避免这样用,但仍是应该对这种现象有所了解,至少知道此种用法性能是很低下的。函数

**********************************************sqlserver

2.“非”操做符不知足SARG形式,使得索引没法使用

不知足SARG形式的语句最典型的状况就是包括非操做符的语句,如:NOT、!=、<>、!、NOT EXISTS、NOT IN、NOT LIKE等。

若是使用not 或者 <>,最好转换成别的方法,好比例子以下:性能

T1表 10000000万条数据,构建以下:(插入时间36分钟,count(*)查询19秒,空间占用670M左右)测试

DECLARE @i INT

SET @i = 1

WHILE @i<1000000

BEGIN

INSERT INTO t1 VALUES ('zhang'+CONVERT(char(50), @i),'3.2',77);

SET @i + 1;

END优化

三种查询方式:编码

SELECT * FROM t1 WHERE id <>300000

SELECT * FROM t1 WHERE id NOT IN (300000)

SELECT * FROM t1 WHERE id >299999 AND id 

在执行计划中能够明显看出,使用最后一种方式而不是前面两种方式进行查询。

网上是这么说的,但本身作的试验100W条数据,开销计划是同样的。server

*********************************************

3. 函数运算不知足SARG形式,使得索引没法使用

例:下列SQL条件语句中的列都建有恰当的索引,但执行速度却很是慢:

select * from record where substring(card_no,1,4)=′5378′(13秒)

select * from record where amount/30

select * from record where convert(char(10),date,112)=′19991201′(10秒)

分析:

where子句中对列的任何操做结果都是在SQL运行时逐列计算获得的,所以它不得不进行全表扫描,而没有使用该列上面的索引;若是这些结果在查询编译时就能获得,那么就能够被SQL优化器优化,使用索引,避免表搜索,所以将SQL重写成下面这样:

select * from record where card_no like ′5378%′(

select * from record where amount 

select * from record where date= ′1999/12/01′ (

你会发现SQL明显快不少

待测试.......

**********************************************

4.尽可能不要对创建了索引的字段,做任何的直接处理

select * from employs where first_name + last_name ='beill cliton';

没法使用索引,改成:

select * from employee where

first_name = substr('beill cliton',1,instr('beill cliton',' ')-1)

and

last_name = substr('beill cliton',instr('beill cliton',' ')+1)

则可使用索引

***********************************************

5.不一样类型的索引效能是不同的,应尽量先使用效能高的

好比:数字类型的索引查找效率高于字符串类型,定长字符串char,nchar的索引效率高于变长字符串varchar,nvarchar的索引。

应该将

where username='张三' and age>20

改进为

where age>20 and username='张三'

注意:此处,SQL的查询分析优化功能能够作到自动重排条件顺序,但仍是建议预先手工排列好。

**************************************************

6.某些状况下IN 的做用与OR 至关 ,且都不能充分利用索引

例:表stuff有200000行,id_no上有非群集索引,请看下面这个SQL:

select count(*) from stuff where id_no in(′0′,′1′) (23秒)

我 们指望它会根据每一个or子句分别查找,再将结果相加,这样能够利用id_no上的索引;但实际上,它却采用了"OR策略",即先取出知足每一个or子句的 行,存入临时数据库的工做表中,再创建惟一索引以去掉重复行,最后从这个临时表中计算结果。所以,实际过程没有利用id_no 上索引,而且完成时间还要 受tempdb数据库性能的影响。

实践证实,表的行数越多,工做表的性能就越差,当stuff有620000行时,执行时间会很是长!若是肯定不一样的条件不会产生大量重复值,还不如将or子句分开:

select count(*) from stuff where id_no=′0′

select count(*) from stuff where id_no=′1′

获得两个结果,再用union做一次加法合算。由于每句都使用了索引,执行时间会比较短,

select count(*) from stuff where id_no=′0′

union

select count(*) from stuff where id_no=′1′

从实践效果来看,使用union在一般状况下比用or的效率要高的多,而exist关键字和in关键字在用法上相似,性能上也相似,都会产生全表扫描,效率比较低下,根据未经验证的说法,exist可能比in要快些。

***************************************************

7.使用变通的方法提升查询效率

like关键字支持通配符匹配,但这种匹配特别耗时。例 如:select * from customer where zipcode like “21_ _ _”,即便在zipcode字段上已创建了索 引,在这种状况下也可能仍是采用全表扫描方式。若是把语句改 为:select * from customer where zipcode >“21000”,在执行查询时就会利用索引,大大提升速度。但 这种变通是有限制的,不该引发业务意义上的损失,对于邮政编码而 言,zipcode like “21_ _ _” 和 zipcode >“21000” 意义是彻底一致的。

*********************************************************人各有志,但富贵在天,人生容许彷徨,但不容许蹉跎.

8.order by按汇集索引列排序效率最高

排序是较耗时的操做,应尽可能简化或避免对大型表进行排序,如缩小排序的列的范围,只在有索引的列上排序等等。

咱们来看:(gid是主键,fariqi是聚合索引列)

select top 10000 gid,fariqi,reader,title from tgongwen

用时:196 毫秒。 扫描计数 1,逻辑读 289 次,物理读 1 次,预读 1527 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by gid asc

用时:4720毫秒。 扫描计数 1,逻辑读 41956 次,物理读 0 次,预读 1287 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by gid desc

用时:4736毫秒。 扫描计数 1,逻辑读 55350 次,物理读 10 次,预读 775 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by fariqi asc

用时:173毫秒。 扫描计数 1,逻辑读 290 次,物理读 0 次,预读 0 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by fariqi desc

用时:156毫秒。 扫描计数 1,逻辑读 289 次,物理读 0 次,预读 0 次。

同时,按照某个字段进行排序的时候,不管是正序仍是倒序,速度是基本至关的。

********************************************************

9.关于节省数据查询系统开销方面的措施

(1)使用TOP尽可能减小取出的数据量

(2)字段提取要按照“需多少、提多少”的原则,避免“select *”

字段大小越大,数目越多,select所耗费的资源就越多,好比取int类型的字段就会比取char的快不少。咱们每少提取一个字段,数据的提取速度就会有相应的提高。提高的幅度根据舍弃的字段的大小来判断

(3)count(*) 与 count(字段) 方法比较

用 count(*)和用 count(主键)的速度是至关的,而count(*)却比其余任何除主键之外的字段汇总速度要快,并且字段越长,汇总速度就越 慢。若是用 count(*), SQL SERVER会自动查找最小字段来汇总。固然,若是您直接写count(主键)将会来的更直接些

(4)有嵌套查询时,尽量在内层过滤掉数据

若是一个列同时在主查询和where子句中出现,极可能当主查询中的列值改变以后,子查询必须从新查询一次。并且查询嵌套层次越多,效率越低,所以应当尽可能避免子查询。若是子查询不可避免,那么要在子查询中过滤掉尽量多的行

(5)多表关联查询时,需注意表顺序,并尽量早的过滤掉数据

在使用Join进行多表关联查询时候,应该使用系统开销最小的方案。链接条件要充份考虑带有索引的表、行数多的表,并注意优化表顺序;说的简单一点,就是尽量早的将以后要作关联的数据量降下来。

通常状况下,sqlserver 会对表的链接做出自动优化。例如:

select name,no from A

join B on A. id=B.id

join C on C.id=A.id

where name='wang'

尽 管A表在From中先列出,而后才是B,最后才是C。但sql server可能会首先使用c表。它的选择原则是相对于该查询限制为单行或少数几行,就可 以减小在其余表中查找的总数据量。绝大多数状况下,sql server 会做出最优的选择,但若是你发觉某个复杂的联结查询速度比预计的要慢,就可使 用SET FORCEPLAN语句强制sql server按照表出现顺序使用表。如上例加 上:SET FORCEPLAN ON…….SET FORCEPLAN OFF 表的执行顺序将会按照你所写的顺序执行。在查询分析器中查看2种执行效 率,从而选择表的链接顺序。SET FORCEPLAN的缺点是只能在存储过程当中使用

原文:http://hi.baidu.com/mayw1985/item/2092f0427fcdf5e6dc0f6cab

转载地址:https://blog.csdn.net/weixin_39987847/article/details/119338714 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:文件服务器监控用户修改信息,文件服务器监控日志软件
下一篇:ftp服务器在线查看文件内容,ftp服务器PDF文件在线查看的实现方法

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月13日 11时46分50秒