索引使用标准(Index Usage Criteria)
为了有效地决定应该创建哪些合适的索引,你必须决定这些索引实际中是否被SQL Server使用过。如果一个索引不能被有效使用,在修改数据时,那只会浪费空间和增加不必要的负担。
需要记住的主要标准是:如果至少是索引的第一列没有被包含在一个有效的搜索参数(search argument SARG)或join子句中,那么SQL Server 就不会使用索引进行更有效地书签查找(bookmark lookup)。
为创建复合索引,选择列的顺序时牢记住这一点,想想下面的在store表中的索引:
Create index nc1_stores on stores (city, state, zip)
下面的每一个查询将会用到索引,因为它们包含了索引的第一列city,其为一个SARG:
select stor_name from stores
where city = 'Frederick'
and state = 'MD'
and zip = '21702'
select stor_name from stores
where city = 'Frederick'
and state = 'MD'
select stor_name from stores
where city = 'Frederick'
and zip = '21702'
然而,下面的查询不会用到索引而进行书签查找,因为它们没指定city列为一个SARG:
select stor_name from stores
where state = 'MD'
and zip = '21702'
select stor_name from stores
where zip = '21702'
引用
注释:
对于前面提到的最后两个查询,如果你显示执行计划(execution plan)信息,你可能发现,查询实际上使用了nc1_store索引来检索了结果集(resultset)。如果再仔细看,你会发现查询没有使用索引最有效地方式——它使用了索引扫描(index scan),而不是索引查找(index seek)。
有关查询存取方法(query aceess method)的更多信息,可参见第35章“Understanding Query Optimization”,在该章中将讲述索引查找。
在索引查找(Index seek)中,SQL Server 沿着索引树(index tree)从根级(root level)向下进行索引键值匹配搜索,直到搜索到指定的行,然后使用存储在索引键值中的书签值(bookmark value)直接从数据页中检索匹配的数据行(这个书签值可以是行标识符(RID),或者聚集索引的键值)。
对一个索引扫描(Index scan),SQL Server搜索索引树中所有叶级(leaf level)中的行来进行可能匹配的查找。如果发现满足匹配的行,然后利用书签检索数据行。
尽管两者都使用了索引,从I/O代价角度来讲,索引扫描比索引查找的代价要高,但比表扫描(Table scan)要略微要小些。然而,本章学习设计索引的目的是为了使用索引查找,所以当我谈到使用索引时,指的是索引查找。
为了得到可能列的书签查询,你可能想到的一个容易的方法是在表中所有列上都创建索引,这样任何类型的查询都可以使用索引了。这种策略可能在某些支持ad hoc queries(随意的查询)的只读的DSS(决策支持系统)环境下是合适的,
但是这样也存在问题,因为仍然会造成有许多索引不被使用。正如你在本章的Index selection节看到的,
不会仅仅因为在某列创建了索引,优化器就总会使用该列的索引,例如,当该列的选择性不够时(not selective enough),就不会使用该列的索引。另外,在一张大表(large table)上创建太多索引会占据数据库中的大量空间,增加了备份的要求时间。前面也提到过,在一个OLTP(在线联机处理)系统上,太多的索引会给数据的插入、修改、删除操作带来大量的额外负担,造成性能上的不利影响。
引用
建议:(每张表4-5个索引)
我曾经常犯的一个设计错误是在OLTP环境下定义了太多的索引。许多情况下,有些索引是冗余的或者是优化器在处理查询时就根本没有考虑。结果,这些索引导致空间的浪费和增加了修改数据时的不必要负担。
在这一点上有一个案例,有个客户在一个表上创建了8个索引,其中4个索引都是在同一列上,该列的键值唯一(unique key),在索引中该列都是第一个索引列。对表的查询和修改操作,该列都包含在where 子句中。结果只有4个的其中1个索引曾被用到过。
希望在本章结束后,你将会理解为什么所有这些索引不是必须的,并且能重新认识和决定在哪些列上创建索引将会收益,而哪些列上应避免创建索引。
自我总结:
1、索引是提高数据库查询速度的重要而有效的手段和方法;
2、索引不是越多越好,因为创建和维护索引是需要付出代价的;
3、创建了索引,查询优化器也不一定用该索引,因为你的查询参数(SARGs)不是有效的,或者因为使用索引付出的代价可能比表扫描(Table Scan)要大;
分享到:
相关推荐
criteria的相关知识及其介绍,便于java编程中使用criteria进行相关操作。
this document is help new developers to quickly learn how to choose Primary index. what's the criteria?
Criteria标准化对象查询小例子,内有配套的SQL表语句和使用说明
介绍了hibernate中 Criteria接口在实际开发过程中的常见使用方法及技巧
DetachedCriteria Criteria 使用方法 非常详细外加练习
hibernate criteria的使用方法
Hibernate中Criteria的使用,对于研究hibrnate源码有一些作用
Hibernate中的Criteria连表查询,包括单表属性查询,多表内连,以及左外连接查询
在上面的代码中,我们首先创建了一个 Criteria 对象,然后使用 `Restrictions.like()` 方法创建了一个条件对象,最后使用 `add()` 方法将条件添加到 Criteria 对象中,并使用 `list()` 方法来获取查询结果。...
Hibernate Criteria 完全使用详解
Hibernate中Criteria的完整用法
这个案例是根据分组查询,并且得到每组的条数,不懂得可以q我:1710086675,欢迎认识更多新朋友
Hibernate中Criteria的完整用法
Hibernate的Criteria用法总结Hibernate的Criteria用法总结
Hibernat 使用Criteria查询多对多关系(SET集合)条件
整体总结Hibernate中的Criteria的用法!
hibernate模糊查询类Criteria的使用
Hibernate-Criteria_模糊查询