背景:

公司业务迅速扩展,很多网站、接口都因为大流量的数据,发生服务器习惯性死机;一条sql查询语句只能适用于一定的网络环境,没有优化的查询当遇上大数据时就不适用了。

本文主旨: 讨论什么情况下能利用上索引.

索引: 创建索引可以根据查询业务的不同分为两种:单一列的索引,联合索引. 顾名思义,单一列索引就是指在表的某一列上创建索引,联合索引是在多个列上联合创建索引.

联合索引-使用结论:

1、查询条件中出现联合索引第一列,或者全部, 则利用联合索引.

2、条件列中只要条件相连在一起, 无论前后, 都会利用上联合索引,

以下为例来说就是:

last_name=’1′ and first_name=’1′

first_name=’1′ and last_name=’1′

3、查询条件中没有出现联合索引的第一列,而出现联合索引的第二列,或者第三列,都不会利用联合索引查询。

单一列索引-使用结论:

1、只要条件列中出现索引列,无论在什么位置,都能利用索引查询.

两者的共同点:

1、要想利用索引,都要符合SARG标准.

2、都是为了提高查询速度.

3、都需要额外的系统开销,磁盘空间.

补充说明: stmtText信息来产生,在查询语句前面加上:SET STATISTICS PROFILE on(SqlServer)/ EXPLAIN (mySql).可以通过运行它,来观察你的查询是否合理,这样才能真正做到优化.

优缺点比较:

1、索引所占用空间:单一列索引相对要小.

2、索引创建时间:单一列索引相对短.

3、索引对insert,update,delete的影响程序:单一列索引要相对低.

4、在多条件查询时,联合索引效率要高.

索引的使用范围:单一列索引可以出现在where 条件中的任何位置,而联合索引需要按一定的顺序来写.

总结:

即使表上创建了索引,但如果查询语句写的不科学的话(不符合SARG标准),也于事无补,要根据表索引情况来优化查询语句,如没有合适的索引可用,则要创建相应索引.

Demo: sqlserver05环境

创建一个人员表,包含人员ID,姓名.在人员ID上创建一个聚集索引,在first_name和last_name上创建一个联合索引.

create table person (id int, last_name varchar(30), first_name varchar(30))

create unique clustered index person_id on person (id)

create index person_name on person (last_name, first_name)

在上例中,id上创建了聚集索引,下面的查询都会用了聚集索引.

where id=1

where id>1

where id<1

where id between 1 and n

where id like ’1%’

where id in(1,2,3…)

说明: id 列出现在条件中的位置并不一定要求第一列,不受位置影响.

不过下面的查询方式则不会用上聚集索引.

where person_id +1=n

where person_id like ‘%5′

where person_id like ‘%5%’

where person_id abs(15)

联合索引列比起单一列索引最大的好处在于,对于多条件的查询它比起单一列索引更加精确.拿上面的人员表来说吧,如果

要查询一个人的全名,只知道first_name是很难马上找到这个人的全名的,如果知道first_name和last_name则会非常容易找到.

下面根据不同的条件输出列顺序说明索引的应用.

第一种情况:–条件和输出列和索引列顺序相同

select last_name,first_name from person where last_name=’1′ and first_name=’1′

stmtText

Index Seek(OBJECT:([bdg_web_vaction].[dbo].[person].[person_name]),

SEEK:([bdg_web_vaction].[dbo].[person].[last_name]=[@1]

AND [bdg_web_vaction].[dbo].[person].[first_name]=[@2]) ORDERED FORWARD)

结果:利用person_name联合索引查找

第二种情况:–条件列与索引列顺序不同,但输出列相同

select last_name,first_name from person where first_name=’1′ and last_name=’1′

stmtText

Index Seek(OBJECT:([bdg_web_vaction].[dbo].[person].[person_name]),

SEEK:([bdg_web_vaction].[dbo].[person].[last_name]=[@2] AND [bdg_web_vaction].

[dbo].[person].[first_name]=[@1]) ORDERED FORWARD)

结果:利用person_name联合索引查找

第三种情况:–条件列与输出列与索引列的顺序都不相同

select first_name,last_name from person where first_name=’1′ and last_name=’1′

Index Seek(OBJECT:([bdg_web_vaction].[dbo].[person].[person_name]),

SEEK:([bdg_web_vaction].[dbo].[person].

[last_name]=[@2] AND [bdg_web_vaction].[dbo].[person].[first_name]=[@1]) ORDERED FORWARD)

结果:利用person_name联合索引查找

第四种情况:–条件列在first_name和last_name中间加入另外一个条件

SELECT id, first_name,last_name from person where first_name=’1′ AND id=1 and last_name=’1′

Clustered Index Seek(OBJECT:([bdg_web_vaction].[dbo].[person].[person_id]),

SEEK:([bdg_web_vaction].[dbo].[person].[id]=CONVERT_IMPLICIT(int,[@2],0)),

WHERE:([bdg_web_vaction].[dbo].[person].[first_name]=[@1] AND [bdg_web_vaction].[dbo].[person].[las

结果:不能利用person_name联合索引查找

第五种情况:--在输出列中分开first_name和last_name

SELECT first_name,id,last_name from person where first_name='1' and last_name='1'

Index Seek(OBJECT:([bdg_web_vaction].[dbo].[person].[person_name]),

SEEK:([bdg_web_vaction].[dbo].[person].

[last_name]=[@2] AND [bdg_web_vaction].[dbo].[person].[first_name]=[@1])

ORDERED FORWARD)

结果:利用person_name联合索引查找

第六种情况:条件列没有出现联合索引的第一列

SELECT first_name,id,last_name from person where first_name=’1′

SELECT first_name,last_name from person where first_name=’1′

SELECT last_name ,first_name from person where first_name=’1′

Index Scan(OBJECT:([bdg_web_vaction].[dbo].[person].[person_name]),

WHERE:([bdg_web_vaction].[dbo].[person].[first_name]=[@1]))

结果:不能利用person_name联合索引.

第七种情况:–条件列出现联合索引的第一列

SELECT first_name,id,last_name from person where last_name=’1′

SELECT first_name,last_name from person where last_name=’1′

SELECT last_name ,first_name from person where last_name=’1′

Index Seek(OBJECT:([bdg_web_vaction].[dbo].[person].[person_name]),

SEEK:([bdg_web_vaction].[dbo].[person].[last_name]=[@1]) ORDERED FORWARD)

结果:利用person_name联合索引查找

SQL 联合索引 与 单一列的索引 比较的更多相关文章

  1. SQL联合索引 与 单一列的索引

    SQL联合索引 与 单一列的索引 标签: sqlwebobjectstatistics优化磁盘 2012-06-12 13:46 27992人阅读 评论(1) 收藏 举报  分类: 数据库(94)  ...

  2. SQL查询优化联合索引 与 单一列的索引

    目前WEB的普及太快,在实际的开发中,一旦遇到大数据量的时候就需要做到优化,让查询的更快,才能给客户更好的体验,也能够在程序上避免timeout. 部分转载自:https://www.cnblogs. ...

  3. 解读SQL Server 2014可更新列存储索引——存储机制

    概述 SQL Server 2014被号称是微软数据库的一个革命性版本,其性能的提升的幅度是有史以来之最. 可更新的列存储索引作为SQL Server 2014的一个关键功能之一,在提升数据库的查询性 ...

  4. SQL Server 2016:内存列存储索引

    作者 Jonathan Allen,译者 谢丽 SQL Server 2016的一项新特性是可以在“内存优化表(Memory Optimized Table)”上添加“列存储索引(Columnstor ...

  5. SQL Server ->> ColumnStore Index(列存储索引)

    Columnstored index是SQL Server 2012后加入的重大特性,数据不再以heap或者B Tree的形式存储(row level)存储在每一个数据库文件的页里面,而是以列为单位存 ...

  6. SQL Server 2014聚集列存储索引

    转发请注明引用和原文博客(http://www.cnblogs.com/wenBlog) 简介 之前已经写过两篇介绍列存储索引的文章,但是只有非聚集列存储索引,今天再来简单介绍一下聚集的列存储索引,也 ...

  7. SQL Server 2016新特性:列存储索引新特性

    SQL Server 2016新特性:列存储索引新特性 行存储表可以有一个可更新的列存储索引,之前非聚集的列存储索引是只读的. 非聚集的列存储索引支持筛选条件. 在内存优化表中可以有一个列存储索引,可 ...

  8. SQL Server 列存储索引概述

    第一次接触ColumnStore是在2017年,数据库环境是SQL Server 2012,Microsoft开始在SQL Server 2012中推广列存储索引,到现在的SQL Server 201 ...

  9. SQL Server 列存储索引 第二篇:设计

    列存储索引可以是聚集的,也可以是非聚集的,用户可以在表上创建聚集的列存储索引(Clustered Columnstore Index)或非聚集的列存储索引(Nonclustered Columnsto ...

随机推荐

  1. android studio常见错误

    1.Failed to import new Gradle project: Could not install Gradle distribution from'http://services.gr ...

  2. hdu 4027 2011上海赛区网络赛G 线段树 成段平方根 ***

    不能直接使用成段增减的那种,因为一段和的平方根不等于平方根的和,直接记录是否为1,是1就不需要更新了 #include<cstdio> #include<iostream> # ...

  3. Servlet中的GET和POST之间的区别

    自己的感悟: get和post这是http协议的两种方法,另外还有head, delete等 这两种方法有本质的区别,get只有一个流,参数附加在url后,大小个数有严格限制且只能是字符串.post的 ...

  4. Cygwin的安装与配置

    去cygwin的官网去下载: 安装: 初次安装 卸载 使用过程中安装新的工具包 参考http://blog.csdn.net/superbinbin1/article/details/10147421 ...

  5. Codeforces Alpha Round #20 (Codeforces format) C. Dijkstra?(裸的dijkstra)

    题目链接:http://codeforces.com/problemset/problem/20/C 思路:需要用优化过的dijkstra,提供两种写法. #include <iostream& ...

  6. MySQL导入sql脚本 导出数据库

    导出数据库 不能停止服务 cd /var/lib/mysql (进入到MySQL库目录,根据自己的MySQL的安装情况调整目录) mysqldump -u用户名 -p 数据库名 > 导出的文件名 ...

  7. JavaScript设计模式——单体模式

    一:单体模式简介: 是什么:将代码组织为一个逻辑单元,这个单元中的代码通过单一的变量进行访问.只要单体对象存在一份实例,就可以确信自己的所有代码使用的是同样的全局资源. 用途:1.用来划分命名空间,减 ...

  8. [自动运维]ant脚本打包,上传文件到指定服务器,并部署

    1.根节点使用,表示根目录为当前目录,默认启动的target为build,项目名称为othersysm, <project basedir="." default=" ...

  9. .NET方向高级开发人员面试时应该事先考虑的问题

    (澄清一下,我发帖的目的不是用来专门给人评价这些问题的好坏的,实际上我所在 的公司就考察这些问题.而能够基本上答出来的可以说百里挑一.如果各位觉得这些问题很简单,那么基本上在.NET面试环节就没有什么 ...

  10. android studio手动加入jar包

    点击启动AndroidStudio,启动后的界面如图所示. 复制你需要添加的jar,并将其黏贴到app— —src— —main— —libs文件夹下,可运行的AndroidStudio项目都有像这样 ...