SQLServer索引调优实践(2)
继续,继续SQLServer索引调优实践。这次探讨一下索引覆盖 - SQL Server主要使用索引去查询你需要的数据,当索引包括所有的你请求查询的字段,SQL Server将不需要去在表中查询。这个概念称做索引覆盖。 SQLServer2005的Non-clustered INDEX增加了一个包含列(i
继续,继续SQLServer索引调优实践。这次探讨一下索引覆盖 - SQL Server主要使用索引去查询你需要的数据,当索引包括所有的你请求查询的字段,SQL Server将不需要去在表中查询。这个概念称做“索引覆盖”。
SQLServer2005的Non-clustered INDEX增加了一个“包含列(included column) ”选项。在 SQL Server 2005 中,可以通过将非键列添加到非聚集索引的叶级别来扩展非聚集索引的功能。通过包含非键列,可以创建覆盖更多查询的非聚集索引。当查询中的所有列都作为键列或非键列包含在索引中时,带有包含性非键列的索引可以显著提高查询性能。这样可以实现性能提升,因为查询优化器可以在索引中找到所有列值;不访问表或聚集索引数据,从而减少磁盘 I/O 操作。
但应避免添加不必要的列。添加过多的索引列(键列或非键列)会对性能产生不良影响,应该合理使用。和Clustered INDEX,或者组合索引,结合使用,扩大索引覆盖,但不大可能所有列都有索引覆盖,磁盘开销和数据insert updat时索引的重新计算的时间开销是巨大的。总之,合理的索引设计是建立在对各种查询的分析和预测上的,只有正确地使索引与程序结合起来,才能产生最佳的优化方案。
继续实践,先建个实验表 Table1:
建两个索引:
1. 主键ID是Clustered INDEX
2. 非聚簇索引Non-Clustered INDEX建立在Age列上,包含列:Count。
CREATE NONCLUSTERED INDEX [cnt] ON [dbo].[table1]
(
[Age] ASC
)
INCLUDE ( [Count])
ON [PRIMARY]
我们的测试SQL语句是:从10万条记录中取出4条记录,两种写法
1. SELECT * FROM table1 WHERE age 2. SELECT count FROM table1 WHERE age
看看运行效率如何:
磁盘IO和时间:
实际执行计划:
性能居然相差20多倍。为什么?
原来第二句Select Count在索引覆盖范围内,因为查询优化器可以在索引中找到所有列值;不访问表或聚集索引数据,从而减少磁盘 I/O 操作。而第一句Select * 选择了所有字段,其中有一个字段Name不在索引覆盖范围内(既不在聚簇索引列,也不在非聚簇索引覆盖列内),SQL Server可以在同一个查询中为一个表使用多个索引,并可以合并多个索引(使用联接算法),以便搜索关键字共同覆盖一个查询。查询分析优化器会自动进行选择, 上述执行计划就是优化的结果,依然比第二个index seek慢了20倍。
然后我又把sql改了一下,变成从10万条记录中取得大部分数据( 返回99900条),小于号改成大于号:
1. SELECT * FROM table1 WHERE age > 100;
2. SELECT count FROM table1 WHERE age > 100;
看看结果:
磁盘IO和时间:
实际执行计划:
依然是第二句索引覆盖的快,这是毋庸置疑的。但第一句执行计划有所不同,SQLServer查询分析优化器选择了不同的策略,改为聚簇索引扫描。上面说过了,SQL Server可以在同一个查询中为一个表使用多个索引,并可以合并多个索引(使用联接算法),以便搜索关键字共同覆盖一个查询。查询分析优化器会自动进行选择, 上述执行计划就是优化的结果。
为何结果集较小和结果集较大SQLServer选择的索引方案不同?
(From园友 高强:当 WHERE age 100时,由于记录数比较多,所以SQL SERVER 认为直接根据聚集索引叶级页面链表扫描页面得出结果更快。不管怎样,最终目的就是在相同结果集情况下,尽可能减少逻辑IO。)
看到这儿,恐怕喜欢用Select*的同学也要节制一下使用了,有时候SQLServer中Select*代价是很高的。当然类似这种SQL是没有问题的,(where exists (select * from ...)),因为SQLServer查询分析优化器会聪明的知道此Select*非彼Select*。
数据库是一个很复杂的系统,即使你不是数据库专家,是应用开发人员,知道一点SQLServer内部更多的东西会有好处,而合理的索引设计是建立在对各种查询的分析和预测上的,只有正确地使索引与程序结合起来, 才能产生最佳的优化方案。
- SQLServer索引调优实践
或许您对以下文章有兴趣:
- 程序员办网站创业,几个问题你想好了吗?
- CTO谈豆瓣网和校内网技术架构变迁
- AJAX延迟异步加载边栏+服务器端缓存AJAX输出
- 二级下拉菜单被遮住,css设置z-index在ie下没作用的问题解决办法
- 简单JS实现走马灯效果的文字(无需jQuery)
- jQuery和ExtJS的timeOut超时设置和event事件处理

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

对于 SQL Server 数据库中已存在同名对象,需要采取以下步骤:确认对象类型(表、视图、存储过程)。如果对象为空,可使用 IF NOT EXISTS 跳过创建。如果对象有数据,使用不同名称或修改结构。使用 DROP 删除现有对象(谨慎操作,建议备份)。检查架构更改,确保没有引用删除或重命名的对象。

导入步骤如下:将 MDF 文件复制到 SQL Server 的数据目录(通常为 C:\Program Files\Microsoft SQL Server\MSSQL\DATA)。在 SQL Server Management Studio(SSMS)中,打开数据库并选择“附加”。单击“添加”按钮,选择 MDF 文件。确认数据库名称,点击确定按钮即可。

当 SQL Server 服务无法启动时,可采取以下步骤解决:检查错误日志以确定根本原因。确保服务帐户具有启动服务的权限。检查依赖项服务是否正在运行。禁用防病毒软件。修复 SQL Server 安装。如果修复不起作用,重新安装 SQL Server。

要查看 SQL Server 端口号:打开 SSMS,连接到服务器。在对象资源管理器中找到服务器名称,右键单击它,然后选择“属性”。在“连接”选项卡中,查看“TCP 端口”字段。

SQL Server 数据库文件通常存储在以下默认位置:Windows: C:\Program Files\Microsoft SQL Server\MSSQL\DATALinux: /var/opt/mssql/data可通过修改数据库文件路径设置来自定义数据库文件位置。

若误删 SQL Server 数据库,可采取以下步骤恢复:停止数据库活动;备份日志文件;检查数据库日志;恢复选项:从备份恢复;从事务日志恢复;使用 DBCC CHECKDB;使用第三方工具。请定期备份数据库并启用事务日志以防止数据丢失。

如果 SQL Server 安装失败,可通过以下步骤清理:卸载 SQL Server删除注册表项删除文件和文件夹重启计算机

SQL Server 英文安装可通过以下步骤更改为中文:下载相应语言包;停止 SQL Server 服务;安装语言包;更改实例语言;更改用户界面语言;重启应用程序。
