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

1.真正充分的利用索引
比如like '张%' 就是符合SARG(符合扫描参数)标准
而like '%张' 就不符合该标准

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

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

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 < 300001

在执行计划中可以明显看出,使用最后一种方式而不是前面两种方式进行查询。
网上是这么说的,但自己做的试验100W条数据,开销计划是一样的。

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

3. 函数运算不满足SARG形式,使得索引无法使用
例:下列SQL条件语句中的列都建有恰当的索引,但执行速度却非常慢:

select * from record where substring(card_no,1,4)=′5378′(13秒)
select * from record where amount/30< 1000(11秒)
select * from record where convert(char(10),date,112)=′19991201′(10秒)

分析:

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

select * from record where card_no like ′5378%′(< 1秒)
select * from record where amount < 1000*30(< 1秒)
select * from record where date= ′1999/12/01′ (< 1秒)

你会发现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的缺点是只能在存储过程中使用

SQLSERVER2008R2正确使用索引的更多相关文章

  1. 正确使用索引(sql优化),limit分页优化,执行计划,慢日志查询

    查看表相关命令 - 查看表结构   desc 表名- 查看生成表的SQL   show create table 表名- 查看索引   show index from  表名 使用索引和不使用索引 由 ...

  2. MySQL之索引以及正确使用索引

    一.MySQL中常见索引类型 普通索引:仅加速查询 主键索引:加速查询.列值唯一.表中只有一个(不可有null) 唯一索引:加速查询.列值唯一(可以有null) 组合索引:多列值组成一个索引,专门用于 ...

  3. 图解MySQL索引(三)—如何正确使用索引?

    MySQL使用了B+Tree作为底层数据结构,能够实现快速高效的数据查询功能.工作中可怕的是没有建立索引,比这更可怕的是建好了索引又没有使用到.本文将围绕着如何优雅的使用索引,图文并茂地和大家一起探讨 ...

  4. 8.7 正确使用索引(no)

    一 索引未命中 并不是说我们创建了索引就一定会加快查询速度,若想利用索引达到预想的提高查询速度的效果,我们在添加索引时,必须遵循以下问题 1 范围问题,或者说条件不明确,条件中出现这些符号或关键字:& ...

  5. javascript使用for循环批量注册的事件不能正确获取索引值的解决方法

    今天遇到一个问题,那就是当使用for循环批量注册事件处理函数,然后最后通过事件处理函数获取当前元素的索引值的时候会失败,先看一段代码实例: <script type="text/jav ...

  6. 用一个性能提升了666倍的小案例说明在TiDB中正确使用索引的重要性

    背景 最近在给一个物流系统做TiDB POC测试,这个系统是基于MySQL开发的,本次投入测试的业务数据大概10个库约900张表,最大单表6千多万行. 这个规模不算大,测试数据以及库表结构是用Dump ...

  7. 正确遍历ElasticSearch索引

    1:ElasticSearch的查询过程 2:由ES查询模式引起的深度分页问题 3:如何正确遍历索引中的数据 ElasticSearch的查询过程 es的数据查询分两步: 第一步是的结果是获取满足查询 ...

  8. Mysql-如何正确的使用索引以及索引的原理

    一. 介绍 二. 索引的原理 三. 索引的数据结构 四. 聚集索引与辅助索引 五. MySQL索引管理 六. 测试索引 七. 正确使用索引 八. 联合索引与覆盖索引 九. 查询优化神器-explain ...

  9. 如何理解并正确使用MySql索引

    原文链接:https://my.oschina.net/feinik/blog/1305784 1.概述 索引是存储引擎用于快速查找记录的一种数据结构,通过合理的使用数据库索引可以大大提高系统的访问性 ...

随机推荐

  1. 项目实例——多表关联查询判断A的字段是否在B中,在显示该字段值,不在显示空;B的字段是否在C中,在显示该字段值,不在显示空。

    1.需求: (1)三张表A.B.C  三个表id相同,如果A表中的name在B表中的bname中显示aname值,否则显示空:如果C表中的addr在B表中的tel显示addr,否则显示空 2.实现方式 ...

  2. RPCL(Rival Penalized Competitive Learning)在matlab下的实现

    RPCL是在线kmeans的改进版,相当于半自动的选取出k个簇心:一开始设定N个簇心,N>k,然后聚类.每次迭代中把第二近的簇心甩开一段距离. 所谓在线kmeans是就是,每次仅仅用一个样本来更 ...

  3. HDU2203 亲和串

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  4. Jenkins实现测试环境到生产环境一键部署(Windows)

    前言: 因为dotnet在发布站点后,然后再上传服务时,会因为各种的网速问题,导致站点瞬间挂掉!那么通过一键部署,先在测试站点测试好的文件,复制到正式站点上的一个缓冲区,进行预热配置,之后再本机进行文 ...

  5. 认识http协议

    http:Hyper Text Transfer Protocol,超文本传输协议.是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准.设计HTTP最初的目的是为了提供一种发布和 ...

  6. Linux下pdf阅读器推荐

    由于需要在pdf文件上做标记,所以自带的文档查看器根本满足了需求,之前去网上查了查,Okular评价挺高,就安装了一个,确实能基本满足我的需求,但是 1.界面感觉还是不太友好,书签栏一直在那. 2.而 ...

  7. [IOS多线程]的使用:防止进行HTTP数据请求时,UI卡死。

    多线程的实现:NSThread 1.子线程的创建:两种方法 第一种: [NSThread detachNewThreadSelector:@selector(downloadImage:) toTar ...

  8. 用Linux命令wget进行整站下载

    wget加上参数之后,即可成为相当强大的下载工具. wget -r -p -np -k http://xxx.com/abc/-r, --recursive(递归) specify recursive ...

  9. 详解使用icomoon生成字体图标的方法并应用

    原文:http://blog.csdn.net/u013938465/article/details/50680468 最近项目大量用到字体图标,大家也知道,字体图标任意缩放不会失真,也大大减少请求数 ...

  10. javascript 代码可读性

    可读性的大部分内容都是和代码缩进相关的,必须保证代码有良好的格式.可读性的另一方面就是注释,一般而言,有如下一些地方需要进行注释 1.1.1 函数和方法 每个函数或方法都应该包含一个注释,描述其目的和 ...