博客
关于我
MSSQL数据库查询优化(一)
阅读量:795 次
发布时间:2023-02-10

本文共 1625 字,大约阅读时间需要 5 分钟。

数据库优化学习(一)

现有一个名为 Orders 的表,包含字段 OrderIdUserIdCreateDateTotalMoneyOrderType。目前该表没有主键和其他索引。为了查询指定日期的订单数量,并返回 OrderIdUserIdTotalMoney 三个字段的数据,我们可以使用以下查询语句:

SELECT OrderId, UserId, TotalMoneyFROM OrdersWHERE CreateDate = '2012-12-17 14:59:53.463';

在执行上述查询时,观察到执行计划显示表扫描(Table Scan)。分析表的数据存储结构可知,该表采用堆存储形式。由于没有索引,查询会逐行检查表数据,评估 CreateDate 这个条件是否为真,从而返回满足条件的行数据。

此时,扫描表操作会涉及表中所有数据行,不管是否满足条件,因此其开销与表的数据量成正比。如果表数据量较少,或者满足条件的数据行比例较大,这样的执行计划是有效的。但如果表数据量较大,而满足条件的数据行比例较小,则会产生大量不必要的数据页和行的I/O开销。

为了优化查询性能,我们可以为表 Orders 创建一个聚集索引:

CREATE CLUSTERED INDEX Orders_OrderId_idx ON Orders(OrderId);

此时,表的数据存储将采用 B-Tree 结构。执行查询时,执行计划显示聚集索引扫描(Clustered Index Scan),取代了之前的表扫描。聚集索引与数据存储在一起,决定了表数据的物理存储顺序。一个表只能有一个聚集索引,其叶子结点存储数据行。聚集索引扫描时,直接访问索引页,而索引页存储整个表的数据副本。通过聚集索引找到记录时,可以直接获取相关列的值。

接下来,我们可以为 CreateDate 字段创建一个非聚集索引:

CREATE NONCLUSTERED INDEX Orders_CreateDate_idx ON Orders(CreateDate);

此时,执行计划显示非聚集索引查找(Nonclustered Index Seek)和检查找(CheckNext)两部分。非聚集索引存储在 B-Tree 中,叶子结点存储记录的 CreateDate 值。非聚集索引查找会通过索引页找到满足条件的记录,然后通过行定位符(RID)访问表中的完整记录。

此时,执行计划中包含键查找(Key Seek)和检查找两部分。键查找通过聚集索引找到满足条件的记录,而检查找则通过非聚集索引查找满足条件的记录。由于查询需要返回 UserIdTotalMoney 两个字段,而这两个字段不在非聚集索引中,优化器需要通过行定位符再次访问表中的记录。

为了避免键查找和检查找的开销,我们可以修改非聚集索引,包含 UserIdTotalMoney 这两个字段:

CREATE NONCLUSTERED INDEX Orders_CreateDate_idx ON Orders(CreateDate)INCLUDE (UserId, TotalMoney);

此时,执行计划显示非聚集索引查找直接访问满足条件的记录,而无需再次通过行定位符访问表中的记录。

如果不创建聚集索引,而直接为 CreateDate 字段创建非聚集索引:

CREATE NONCLUSTERED INDEX Orders_CreateDate_idx ON Orders(CreateDate);

则执行计划显示行定位符查找(RID Seek),即通过行定位符直接访问满足条件的记录。这与之前的键查找和检查找方式相比,仅涉及单个迭代器。

综上所述,合理设计索引覆盖查询所需字段,可以显著优化查询性能,避免不必要的二次查找操作。通过优化索引设计,可以将 I/O 开销降到最低,从而提升数据库查询效率。

转载地址:http://haffk.baihongyu.com/

你可能感兴趣的文章
mysql中null和空字符串的区别与问题!
查看>>
MySQL中ON DUPLICATE KEY UPDATE的介绍与使用、批量更新、存在即更新不存在则插入
查看>>
MYSQL中TINYINT的取值范围
查看>>
MySQL中UPDATE语句的神奇技巧,让你操作数据库如虎添翼!
查看>>
Mysql中varchar类型数字排序不对踩坑记录
查看>>
MySQL中一条SQL语句到底是如何执行的呢?
查看>>
MySQL中你必须知道的10件事,1.5万字!
查看>>
MySQL中使用IN()查询到底走不走索引?
查看>>
Mysql中使用存储过程插入decimal和时间数据递增的模拟数据
查看>>
MySql中关于geometry类型的数据_空的时候如何插入处理_需用null_空字符串插入会报错_Cannot get geometry object from dat---MySql工作笔记003
查看>>
mysql中出现Incorrect DECIMAL value: '0' for column '' at row -1错误解决方案
查看>>
mysql中出现Unit mysql.service could not be found 的解决方法
查看>>
mysql中出现update-alternatives: 错误: 候选项路径 /etc/mysql/mysql.cnf 不存在 dpkg: 处理软件包 mysql-server-8.0的解决方法(全)
查看>>
Mysql中各类锁的机制图文详细解析(全)
查看>>
MySQL中地理位置数据扩展geometry的使用心得
查看>>
Mysql中存储引擎简介、修改、查询、选择
查看>>
Mysql中存储过程、存储函数、自定义函数、变量、流程控制语句、光标/游标、定义条件和处理程序的使用示例
查看>>
mysql中实现rownum,对结果进行排序
查看>>
mysql中对于数据库的基本操作
查看>>
Mysql中常用函数的使用示例
查看>>