zoukankan      html  css  js  c++  java
  • SQL 联合索引 与 单一列的索引 比较

    背景:

    公司业务迅速扩展,很多网站、接口都因为大流量的数据,发生服务器习惯性死机;一条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联合索引查找

  • 相关阅读:
    Pocket Cube
    善意的投票(最大流)
    清明梦超能力者黄YY(idx数组)
    Inside Triangle
    孤岛营救问题(BFS+状压DP)
    餐巾计划问题(费用流)
    Lunch Time(费用流变型题,以时间为费用)
    71. Simplify Path
    70. Climbing Stairs
    69. Sqrt(x)
  • 原文地址:https://www.cnblogs.com/fightingtong/p/3554248.html
Copyright © 2011-2022 走看看