日期:2014-05-17  浏览次数:20744 次

大虾们谈谈索引
今天和人谈索引的时候碰到几个问题,情景是这样的:
有表A,表结构为(ID,A,B),其中ID是主键,然后又在表A建了一个复合索引[ID asc,A asc,B asc]
问题是
1.一次查询中,一个表可以同时走两个索引吗?
2.我分别建[A asc]和[B asc]的索引,与[A asc,B asc]的复合索引等价吗?不等价的话有什么区别?

------解决方案--------------------
问题1:可以
问题2:不等价,复合索引的统计信息只保留第一列的,后面那些列的统计信息不保留,所以符合索引的首列选择非常重要。而拆开来键索引,每个都有统计信息。统计信息对优化器选择索引非常重要。
------解决方案--------------------
1.一次查询中,一个表可以同时走两个索引吗?
--> 不一定,看查询语句和执行计划..

2.我分别建[A asc]和[B asc]的索引,与[A asc,B asc]的复合索引等价吗?不等价的话有什么区别?
--> 不等价,索引内容不同,执行时选用方法不同.
------解决方案--------------------
1、视情况而定
2、分几种情况:
WHERE A = XXX:算法复杂度[A asc]==[A asc,B asc],空间复杂度[A asc]<[A asc,B asc]
WHERE A = XXX AND B = XXX:算法复杂度[A asc]和[B asc]>[A asc,B asc],空间复杂度[A asc]和[B asc]>[A asc,B asc]
WHERE B = XXX:索引[B asc]启用,索引[A asc,B asc]无效

综上所述,不管怎么玩,[A asc]和[A asc,B asc]只需要保留一个
如果只有WHERE A = XXX AND B = XXX 或者 WHERE A = XXX 这样的查询 ,保留[A asc,B asc]就可以了
如果有WHERE B = XXX 建议用 [A asc]和[B asc]
------解决方案--------------------
索引怎么建,要看你的sql语句,也就是你的表的用法,单纯对着表来整索引并不有意义。
------解决方案--------------------
http://www.cnblogs.com/worfdream/articles/2840582.html
------解决方案--------------------
1、查询分析器会根据开销来确定是否使用什么样的索引,而开销则是根据你的T-SQL语句来评估的,因此,你的T-SQL语句决定走什么样的索引。
2、不一样,同样也是基于T-SQL语句,走什么样的索引根据你的T-SQL语句的每一步开销来决定。
------解决方案--------------------
1. 可以的。但要看你的语句。
2. 不一样。各位大神已经解答。
主要是看查询语句,而来讨论索引结构。很多开发人员存在一个误区:一个表,每个列上建一个单列索引,那么无论查询怎么写都会走索引,查询就会快了。
走是走索引了,但是于查询性能没有提升是没有意义的。一大堆index scan,lookup是没有用的。
------解决方案--------------------

虽然不知道你们说些什么,但是感觉你们很牛B
------解决方案--------------------
有索引,查询肯定是快了
如果不影响插入、修改的效率,多点索引也没错(数据库文件会大)
------解决方案--------------------
引用:
索引怎么建,要看你的sql语句,也就是你的表的用法,单纯对着表来整索引并不有意义。


借宝地问一下,如果能够看到某个索引有没有被使用过???好像Oracle有这个功能吧??SQL Server有没有类似的功能??
------解决方案--------------------
引用:
Quote: 引用:

索引怎么建,要看你的sql语句,也就是你的表的用法,单纯对着表来整索引并不有意义。


借宝地问一下,如果能够看到某个索引有没有被使用过???好像Oracle有这个功能吧??SQL Server有没有类似的功能??

判断无用索引:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT TOP 30
        DB_NAME() AS DatabaseName ,