sql中索引不会被用到的几种情况

1、查询谓词没有使用索引的主要边界,可能会导致不走索引。比如,你查询的是SELECT * FROM T WHERE Y=XXX;假如你的T表上有一个包含Y值的组合索引,但是优化器会认为需要一行行的扫描会更有效,这个时候,优化器可能会选择TABLE ACCESS FULL,但是如果换成了SELECT Y FROM T WHERE Y = XXX,优化器会直接去索引中找到Y的值,因为从B树中就可以找到相应的值。
2、如果在B树索引中有一个空值,那么查询诸如SELECT COUNT(*) FROM T 的时候,因为HASHSET中不能存储空值的,所以优化器不会走索引,有两种方式可以让索引有效,一种是SELECT COUNT(*) FROM T WHERE XXX IS NOT NULL或者是不能为空。
3、如果在T表上有一个索引Y,但是你的查询语句是这样子SELECT * FROM T WHERE FUN(Y) = XXX。这个时候索引也不会被用到,因为你要查询的列中所有的行都需要被计算一遍,因此,如果要让这种sql语句的效率提高的话,在这个表上建立一个基于函数的索引,比如CREATE INDEX IDXFUNT ON T(FUN(Y));这种方式,等于Oracle会建立一个存储所有函数计算结果的值,再进行查询的时候就不需要进行计算了,因为很多函数存在不同返回值,因此必须标明这个函数是有固定返回值的。
4、索引不适用于隐式转换的情况,比如你的SELECT * FROM T WHERE Y = 5 在Y上面有一个索引,但是Y列是VARCHAR2的,那么Oracle会将上面的5进行一个隐式的转换,SELECT * FROM T WHERE TO_NUMBER(Y) = 5,这个时候也是有可能用不到索引的。
5、在Oracle的初始化参数中,有一个参数是一次读取的数据块的数目,比如你的表只有几个数据块大小,而且可以被Oracle一次性抓取,那么就没有使用索引的必要了,因为抓取索引还需要去根据rowid从数据块中获取相应的元素值,因此在表特别小的情况下,索引没有用到是情理当中的事情。
6、很长时间没有做表分析,或者重新收集表状态信息了,在数据字典中,表的统计信息是不准确的,这个情况下,可能会使用错误的索引,这个效率可能也是比较低的。


在《Oracle专家编程》Pdf中,有一个非常不错的例子,在本机实际做一下,能对索引有一个更深的印象,大致就是
CREATE TABLE FOO(USERNAME VARCHAR2(100) PRIMARY KEY,USERID VARCHAR2(100));
产生一堆数据,然后查询SQL
CREATE TABLE FOOBAK SELECT * FROM FOO ORDER BY USERID DESC;
然后给USERNAME加上主键索引,然后查询SQL
能够看到两个使用了USERNAME pk 的索引,产生了不同的执行计划,这个实实在在的说明了表的物理结构实实在在的影响了执行计划。
<think>好的,用户想知道如何通过SQL Server的查询执行计划来分析是否使用索引。首先,我需要回忆一下相关知识,并结合之前提供的引用内容来组织答案。用户的问题集中在执行计划的分析,特别是索引使用情况。根据引用内容,比如引用[2]和引用[4],提到了执行计划中的索引查找和键查找,以及如何查看索引使用情况。我需要先解释如何获取执行计划,然后如何解读其中的关键部分。 首先,获取执行计划的方法可能有几种,比如在SSMS中直接使用“包括实际执行计划”的选项,或者使用SET STATISTICSXMLON。这些方法在引用[3]中也有提到,关于保存同版本执行计划进行比较。接下来,分析执行计划时,需要关注哪些操作符。索引扫描(IndexScan)和索引查找(Index Seek)的区别很重要。索引扫描可能意味着没有有效利用索引,而索引查找则说明使用索引。引用[2]中提到非聚集索引的查找和键值查找,这可能涉及到RID或键查找,说明需要回表获取数据,这时候可能影响性能。然后,如何判断是否使用索引?用户可能需要查看执行计划中的操作符,比如有没有出现Index Seek,或者是否有扫描操作。此外,引用[4]中的查询可以用来查看索引使用情况,比如sys.dm_db_index_usage_stats,这可能也是一个补充方法。另外,用户可能需要优化建议,比如缺失索引提示。执行计划有时会提示缺失的索引,这需要提到。引用[3]中的优化最佳实践部分可以支持这一点。还要注意可能的陷阱,比如书签查找(Key Lookup)虽然使用索引,但可能效率高,需要结合覆盖索引来优化。引用[2]中的例子正好说明了这种情况,非聚集索引缺少某些列导致需要回表查询,这时候可能需要调整索引。最后,确保步骤清晰,从获取执行计划到分析关键点,再到优化建议,逐步引导用户完成分析。同时,生成的相关问题需要围绕索引使用和执行计划分析展开,比如如何优化索引、解决键查找问题等。</think>### 如何通过SQL Server查询执行计划分析索引使用情况? #### 一、获取执行计划的3种方法 1. **图形化执行计划** 在SSMS中执行查询时,点击「包括实际执行计划」按钮(快捷键:$Ctrl+M$),结果页会生成可视化执行流程图。图标中绿色箭头表示索引查找(Index Seek),红色箭头表示索引扫描(Index Scan)[^2][^3]。 2. **文本执行计划** ```sql SET SHOWPLAN_TEXT ON; GO -- 执行目标查询 GO SET SHOWPLAN_TEXT OFF; ``` 3. **XML格式执行计划** ```sql SET STATISTICS XML ON; -- 执行目标查询 SET STATISTICS XML OFF; ``` #### 二、分析执行计划的4个关键点 1. **索引查找(Index Seek)** - 符号:绿色箭头图标 - 含义:通过B+树直接定位数据行,效率高 - 示例:`NonClustered Index Seek (SEEK:([firstname]=N'John'))`[^2] 2. **索引扫描(Index Scan)** - 符号:红色箭头图标 - 含义:遍历整个索引叶子节点 - 常见场景:无适合的WHERE条件、统计信息过时 3. **键查找(Key Lookup)** - 符号:嵌套在索引查找后的黄色箭头 - 问题:通过非聚集索引找到主键后,需回聚集索引取其他列 - 优化方案:创建覆盖索引(INCLUDE缺失列)[^2] 4. **缺失索引提示** ```xml <MissingIndexes> <MissingIndexGroup Impact="94.413"> <MissingIndex Database="[DB]" Schema="[dbo]" Table="[Employees]"> <ColumnGroup Usage="EQUALITY"> <Column Name="[DepartmentID]"/> </ColumnGroup> </MissingIndex> </MissingIndexGroup> </MissingIndexes> ``` #### 三、验证索引使用的2种补充方法 1. **索引使用统计查询** ```sql SELECT i.name AS IndexName, user_seeks + user_scans + user_lookups AS TotalReads FROM sys.dm_db_index_usage_stats us JOIN sys.indexes i ON us.object_id = i.object_id AND us.index_id = i.index_id WHERE us.object_id = OBJECT_ID('YourTable'); ``` 2. **Query Store分析** ```sql ALTER DATABASE YourDB SET QUERY_STORE = ON; SELECT qsp.query_id, qsqt.query_sql_text, qsp.plan_id, qsp.is_forced_plan FROM sys.query_store_plan qsp JOIN sys.query_store_query qsq ON qsp.query_id = qsq.query_id JOIN sys.query_store_query_text qsqt ON qsq.query_text_id = qsqt.query_text_id; ``` #### 四、典型问题案例分析 **场景**:某查询在`WHERE City='London'`时出现`Clustered Index Scan` **诊断步骤**: 1. 检查是否存在`City`字段的索引:`EXEC sp_helpindex 'Customers';` 2. 确认索引包含必要字段:若需返回`Phone`字段,建议创建`CREATE INDEX IX_City ON Customers(City) INCLUDE (Phone)` 3. 更新统计信息:`UPDATE STATISTICS Customers;` #### 五、优化建议 1. 对高频率查询字段建立复合索引 2. 定期重建碎片率超过30%的索引 3. 避免在WHERE条件中对索引列进行函数运算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值