sql server 2008学习4 设计索引的建议
索引设计的建议:
一.检查where子句和连接条件列
当一个查询提交到sql server时,查询优化器尝试为查询中引用的所有表查找最佳的数据访问机制,
一下是它所进行的方式。
1.优化器识别Where子句和连接条件中包含的列、
2.接着优化器检查这些列的索引.
3.优化器通过从索引上维护的统计确定子句的选择性(也就是返回多少行),评估每个索引的有效性
4.最终,优化器根据前面几个步骤中收集的信息,评估读取所限定的行开销最低的方法.
下面看个例子: Table_1表内 又 30000条数据
执行查询:
查看结果:
逻辑读取的次数为 95次.
下面加上where 条件句, where 的列 是 含有聚集索引的.
结果:
很明显, 逻辑读 次数减少了两次.
下面看 where 条件句,where 的列 不含有索引的:
查询的结果:
总结:
where 子句列 帮助 优化器选择 一个对 查询最优的索引操作. 这也使用于 两个表之间的连接条件中使用的列.
优化器 查找在 where子句 或连接条件列上的索引,如果可用,考虑使用该索引 来从表中检索行,查询优化器在执行一个查询时,
考虑where子句或连接条件列上的索引. 因此,在where子句或连接条件中 频繁使用的列上有 索引将 帮助查询优化器避免基本表的扫描.
注意: 当一个表中的数据总量非常小以至于可以 放入一个单独的页面(8kb)时,表扫描可能比索引查找工作 得更好,
二: 使用 窄索引
应该避免在索引中使用 宽数据类型 的列. 比如 字符串类型(char,varchar,nchar ,nvarchar)的列有时候可能和二进制类型一样大.
窄索引可以再8kb的索引页面中 容纳比 宽索引 更多的行,这将有一下效果:
1.减少 i/o数量 (读取更少的8kb页面)
2.使数据库缓存更有效,因为 sql server 可以缓存更少的索引页面,从而减少内存中的索引页面所需的逻辑读操作.
3.减少数据库的存储空间.
下面看个例子:
表a
id为主键, 所以 a有个聚集索引, 那么id列的数据类型是 int,a表有数据27行数据,
说明所有的 索引 总大小为 4*27 byte, 一个索引页面(8kb)完全可以容得下.
sys.indexes系统表 在每个数据库中保存,包含了数据库中所有索引的基本信息.
DMF sys.dm_db_index_physical_stats 包含了关于索引上统计的更详细信息.
下面看sql语句:
select i.name,i.type_desc,s.page_count,s.record_count,s.index_level from sys.indexes ijoin sys.dm_db_index_physical_stats(DB_ID(N'test'),OBJECT_ID(N'dbo.a'),null,null,'DETAILED') as son i.index_id=s.index_id where i.OBJECT_ID=OBJECT_ID(N'dbo.a')
获取如下 结果:
.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) } .csharpcode pre { margin: 0 } .csharpcode .rem { color: rgba(0, 128, 0, 1) } .csharpcode .kwrd { color: rgba(0, 0, 255, 1) } .csharpcode .str { color: rgba(0, 96, 128, 1) } .csharpcode .op { color: rgba(0, 0, 192, 1) } .csharpcode .preproc { color: rgba(204, 102, 51, 1) } .csharpcode .asp { background-color: rgba(255, 255, 0, 1) } .csharpcode .html { color: rgba(128, 0, 0, 1) } .csharpcode .attr { color: rgba(255, 0, 0, 1) } .csharpcode .alt { background-color: rgba(244, 244, 244, 1); width: 100%; margin: 0 } .csharpcode .lnum { color: rgba(96, 96, 96, 1) }
说明 索引页数 是1页, index_leval =0说明是 聚集索引.
下面使用宽索引 的一个例子:
b表结果如下: name列有一个 非聚集索引,索引名字为: IX_b 由于name 的数据类型为 char(500),b内数据有23行, 说明非聚集索引占用的大小事 23*500byte,那么超出了一个页面的大小,
按照预测,name的索引将存在两个索引页面, 下面用sql语句来证实这个结论.
sql语句:
select i.name,i.type_desc,s.page_count,s.record_count,s.index_level from sys.indexes ijoin sys.dm_db_index_physical_stats(DB_ID(N'test'),OBJECT_ID(N'dbo.b'),null,null,'DETAILED') as son i.index_id=s.index_id where i.OBJECT_ID=OBJECT_ID(N'dbo.b')
.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) } .csharpcode pre { margin: 0 } .csharpcode .rem { color: rgba(0, 128, 0, 1) } .csharpcode .kwrd { color: rgba(0, 0, 255, 1) } .csharpcode .str { color: rgba(0, 96, 128, 1) } .csharpcode .op { color: rgba(0, 0, 192, 1) } .csharpcode .preproc { color: rgba(204, 102, 51, 1) } .csharpcode .asp { background-color: rgba(255, 255, 0, 1) } .csharpcode .html { color: rgba(128, 0, 0, 1) } .csharpcode .attr { color: rgba(255, 0, 0, 1) } .csharpcode .alt { background-color: rgba(244, 244, 244, 1); width: 100%; margin: 0 } .csharpcode .lnum { color: rgba(96, 96, 96, 1) }
查询结果如下:
果然,看到 IX_b record_count =23的 行, 它的 page_count是2 ,说明我们之前的猜想是正确的.
这就是宽索引的劣势.
三:检查列的唯一性.
在一个具有很小范围的可能值的列(如性别,只有,f和m)上创建索引,对性能是没有很大帮助的.
因为查询优化器不能使用索引有效的减少返回的行.
考虑只有两个唯一值 的 性别列(F和M).当执行一个 具有使用 性别列的where子句查询时,最终从表中得打很大数量的行,导致开销很大的表,或聚集索引扫描.
结论:
所以 使用where子句中的列 具有 大量的唯一行,一限制访问的行数,是个首选的方案. 应该在 这些列上 创建索引,来帮助 查询优化器
访问小的结果集.
而且,在创建多个列上的索引时(符合索引),列的顺序是有关系的.在某些情况下,先使用最有选择性的列将使索引行的列更有效率.
可以使用下面的语句 来判断 列的选择性.
test1 自己随意定义的表select count(distinct EventClass) as 不同的值,count(EventClass) as 多少行,cast(count(distinct EventClass) as decimal) as 选择性 from test1
结果如下:
具有最高的唯一值数量(或选择性)的列 是 where子句 或连接条件 中引用的索引的 最佳候选.
四:考虑索引类型
`sql server主要有两种索引,聚集索引和非聚集索引,这两种类型的索引 都为 B-树 结构。两者之间的主要区别 是
聚集索引的叶子页面 是表的数据页面,因此数据和其指针的顺序相同,这意味着 聚集索引就是该表。
下一篇 ,主要讲述这两种索引。
sql server 2008学习4 设计索引的建议相关推荐
- sql server 2008 学习笔记
sql server 2008 删除已有的实例 想从setup.exe中区卸载,没找到. 原来还是要从控制面板中卸载,卸载Microsoft SQL Server 2008 卸载界面会提示让你选择要删 ...
- sql server 2008学习8 sql server存储和索引结构
sql server的存储机制 区段: 是用来为表和索引 分配空间的基本存储单元. 由 8个连续的页面构成,大小为64kb. 区段的注意事项: 一旦区段已满,那么下一记录 将要占据的空间不是记录的大小 ...
- sql server 2008学习3 表组织和索引组织
表组织 表包含在一个或多个分区中,每个分区在一个堆或一个聚集索引结构包含数据行.堆页或聚集索引页在一个或多个分配单元中进行管理,具体的分配单元数取决于数据行中的列类型. 聚集表.堆和索引 SQL Se ...
- sql server 2008学习12 事务和锁
事务 事务的点: 1.begin tran 是事务开始的地方,也是 事务回滚的起点.也就说他会忽略这个起点之后的最终没有提交的所有语句, 2.commit tran 事务的提交 是一个事务的终点 当发 ...
- sql server 2008学习1–系统数据库
master数据库 数据库记录 SQL Server 系统的所有系统级信息.这包括实例范围的元数据(例如登录帐户).端点.链接服务器和系统配置设置.此外,master 数据库还记录了所有其他数据库的存 ...
- sql server 2008学习2 文件和文件组
数据库文件 每个 SQL Server 数据库至少具有两个操作系统文件:一个数据文件和一个日志文件.数据文件包含数据和对象,例如表.索引.存储过程和视图.日志文件包含恢复数据库中的所有事务所需的信息. ...
- sql server 2008学习10 存储过程
输入输出参数: 给存储过程传参数,叫做输入参数,用户告诉存储过程需要 利用这个参数干些什么. 输出参数: 从存储过程得到那些数据. 创建一个可选参数的存储过程: create proc pa1 @na ...
- sql server 2008学习9 视图
创建简单视图: use test go create view v1(视图名) as select name from b 这样视图就创建好了. 下面说下视图的本质: 当执行 select * fr ...
- sql server 2008学习5 sql基础
查看数据库的信息: INFORMATION_SCHEMA.CHECK_CONSTRAINTS INFORMATION_SCHEMA.COLUMN_DOMAIN_USAGE INFORMATION_SC ...
最新文章
- 2022-2028年中国高纯铜市场研究及前瞻分析报告
- iscsi发起程序找不到目标_3分钟学会程序员“面试回答规范”,不怕找不到工作的里面请...
- 30 个 OpenStack 经典面试问题和解答
- 快春运了,做个火车余票查询接口,余票来源12306,图是百度地图
- 如何部署 Hyperic ,使得从内网监测外网服务器
- 【Siddhi】Flink Siddhi房间温度上升5度报警案例
- Vue中的join(),reverse()与 split()函数
- 求方程式ax2 bx c=0的根c语言,关于求方程ax2+bx+c=0根的问题
- Atitit. 异常的使用总结最佳实践java .net php Vo8f
- 啊哈算法——第一章第二节:冒泡排序
- 蓝桥杯真题:k倍区间
- linux 怎么关闭输入法快捷键设置方法,关闭输入法快捷键
- 如何将npy导入matlab,如何在Matlab中读取.npy文件(How to read .npy files in Matlab)
- QT 录制音频(麦克风、系统)
- 路由器原理和路由协议介绍
- 计算机怎么打字快,电脑新手如何快速打字?
- 姿态估计1-03:FSA-Net(头部姿态估算)-白话给你讲论文-翻译无死角(1)
- 能够切换用户重新登录计算机,苹果电脑切换用户登录_苹果电脑切换登录账号...
- Vue 事件修饰符.self的用法
- 抢购倒计时自定义控件的实现与优化
热门文章
- C++成员变量和成员函数分开存储
- C语言编写2048小游戏
- ontouchevent android,android onTouchEvent处理机制总结(必看)
- Redash 9安装与配置(基于Docker方式)
- 窗口分析函数_10_计算组总和的占比
- 学生出勤率平时成绩java_《javaweb应用开发》课程标准.doc
- C语言单片机数码管a段亮,各位大神,如何用C语言实现在数码管上实现1234同时亮...
- C++递归求数组最大值、平均值、求和
- datax源码阅读二:Engine流程
- org.apache.poi 读取数字问题