怎样才能充分利用SQL索引

原文:怎样才能充分利用SQL索引

     背景:目前WEB的普及太快,很多网站都会因为大流量的数据而发生服务器习惯性死机,一个查询语句只能适用于一定的网络环境.没有优化的查询当遇上大数据量时就不适用了.

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

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

     优缺点比较:

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

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

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

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

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

    本文所用测试软件环境如下:SQL05  

      DEMO:创建一个人员表,包含人员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联合索引查找

      联合索引使用总结:

         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.可以通过运行它,来观察你的查询是否合理,这样才能真正做到优化.

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

 

 

          

 

  

 

时间: 2024-12-05 15:47:23

怎样才能充分利用SQL索引的相关文章

软件开发人员真的了解SQL索引吗(索引使用原则)

原文:软件开发人员真的了解SQL索引吗(索引使用原则)     前两篇文章我总结了一些SQL数据库索引的问题,这篇主要来分析下索引的优缼点,以及如何正确使用索引.       索引的优点:这个显而易见,正确的索引会大大提高数据查询,对结果进行排序.分组的操作效率.    索引的缺点:优点显而易见,同样缺点也是显而易见:    1:创建索引需要额外的磁盘空间,索引最大一般为表大小的1.2倍左右.    2:在表数据修改时,例如增加,删除,更新,都需要维护索引表,这是需要系统开销的.    3:不合

充分利用SQL Server Reporting Services图表

本文适用于Microsoft SQL Server 2005 Reporting Services 简介 本白皮书讲述如何在 Microsoft SQL Server Reporting Services 报表中设计图表.本文分为几部分 并引用特定的报表示例:它们包含在示例项目下载中. 第一部分为数据准备,此部分主要包括有关准备数据的特定信息.技巧和见解.第二部分为图表标签 ,此部分讲述如何应用标签设置来改进图表和控制视觉外观和效果. 示例图表和报表部分讲述如何充分利用 SQL Server R

SQL——索引

原文:SQL--索引   1. 什么是索引     索引是SQlServer编排数据的内部方法,是检索表中数据的直接通道.它类似汉语词典里面 的拼音目录,通过它可以快速查找到某个字词.     索引页是数据库中存储说要的数据页.索引页存放检索数据行的关键字页及数据行的地址指针.索引页类似于汉语字典中按拼音或笔画排序的目录页.   2. 索引分类     唯一索引: 创建唯一约束会自动创建唯一索引. 它对应的列中仅允许有一个null值.    主键索引: 是唯一索引的一种特殊类型.创建主键会自动创

怎么才能限制SQL Server只能让指定的机器连接_oracle

正在看的ORACLE教程是:怎么才能限制SQL Server只能让指定的机器连接. Q. How can I restrict access to my SQL Server so that it only allows certain machines to connect?(v1.0 19.10.1998) 怎样才能限制我的SQL Server只能让指定的机器连接 A. SQL Server has no built-in tools/facilities to do this. It al

sql索引-sql建索引之后的查询时间提高不大

问题描述 sql建索引之后的查询时间提高不大 我的索引是创建在uid上面,uid是int类型的,我在网上看到有个帖子,1000万条数据查询处25万条数据,加了索引之后用了2秒.没用索引之前利用表扫描用了128秒.然后我在1000万条数据中查询24万条,用了索引之后只提升了2秒不到..求指导啊拜托大神教一教 解决方案 A)128秒和2秒的条件都不一样,没有可比性.B)索引可以保证性能不会很差.并不表示不建索引肯定会差,这受到数据量大小.碎片多少.缓存情况等各种影响,波动很大.你正好碰到表现比较好的

怎样才能限制SQL Server只能让指定的机器连接(转)

server Q. How can I restrict access to my SQL Server so that it only allows certain machines to connect?(v1.0 19.10.1998) 怎样才能限制我的SQL Server只能让指定的机器连接 A. SQL Server has no built-in tools/facilities to do this. It also does not have the facility to ru

怎样才能限制SQL Server只能让指定的机器连接

server Q. How can I restrict access to my SQL Server so that it only allows certain machines to connect?(v1.0 19.10.1998) 怎样才能限制我的SQL Server只能让指定的机器连接 A. SQL Server has no built-in tools/facilities to do this. It also does not have the facility to ru

SQL索引优化方法

SELECT TOP 50 ROW_NUMBER() OVER(ORDER BY ResumeCreateTime DESC) as [RowID] ,[TopDegree] ,[DegreeRankID] ,[UserResume].[UserResumeID] ,[UserResume].[UserID] ,[ResumeName] ,[BirthDate] ,[WorkStartedDate] ,[SalaryNeeded] ,[BufferTimeSpanID] ,[ResumeCrea

来,我们讨论下如何怎么才能让Sql执行的快。

发现问题 系统业务性能表现 Mysql慢日志.看这里 Mysql主机 CPU负载过高 RDS等云数据库得监控 增加慢sql层,比如利用Spring AOP重写数据源,增加慢Sql告警 explain命令发现使用where条件而没有命中任何索引,或者是为了得到返回结果用到了太多的行.返回结果中.type对应了查询所使用的类型,比如All代表全表扫描,ref代表索引扫描,还会有范围扫描.唯一索引扫描等等.最好都能够达到ref的级别. Mysql 整体结构 在解决慢Sql问题之前,先看一下Mysql的