加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql-server – 为什么SQL Server会忽略索引?

发布时间:2020-12-12 16:59:24 所属栏目:MsSql教程 来源:网络整理
导读:我有一个表,CustPassMaster有16列,其中一个是CustNum varchar(8),我创建了一个索引IX_dbo_CustPassMaster_CustNum.当我运行我的SELECT语句时: SELECT * FROM dbo.CustPassMaster WHERE CustNum = '12345678' 它完全忽略了索引.这让我感到困惑,因为我有另一个
我有一个表,CustPassMaster有16列,其中一个是CustNum varchar(8),我创建了一个索引IX_dbo_CustPassMaster_CustNum.当我运行我的SELECT语句时:
SELECT * FROM dbo.CustPassMaster WHERE CustNum = '12345678'

它完全忽略了索引.这让我感到困惑,因为我有另一个表CustDataMaster,其中包含更多列(55),其中一个是CustNum varchar(8).我在此表中创建了此列的索引(IX_dbo_CustDataMaster_CustNum),并使用了几乎相同的查询:

SELECT * FROM dbo.CustDataMaster WHERE CustNum = '12345678'

它使用我创建的索引.

这背后有什么具体的推理吗?为什么它会使用CustDataMaster中的索引,而不是来自CustPassMaster的索引?这是由于列数低吗?

第一个查询返回66行.对于第二行,返回1行.

另外需要注意:CustPassMaster有4991条记录,CustDataMaster有5376条记录.这可能是忽略指数的原因吗? CustPassMaster还具有具有相同CustNum值的重复记录.这是另一个因素吗?

我将此声明基于两个查询的实际执行计划结果.

以下是CustPassMaster的DDL(具有未使用索引的DDL):

CREATE TABLE dbo.CustPassMaster(
    [CustNum] [varchar](8) NOT NULL,[Username] [char](15) NOT NULL,[Password] [char](15) NOT NULL,/* more columns here */
    [VBTerminator] [varchar](1) NOT NULL
) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IX_dbo_CustPassMaster_CustNum] ON dbo.CustPassMaster
(
    [CustNum] ASC
) WITH (PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,SORT_IN_TEMPDB = OFF,DROP_EXISTING = OFF,ONLINE = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

而CustDataMaster的DDL(我省略了很多不相关的字段):

CREATE TABLE dbo.CustDataMaster(
    [CustNum] [varchar](8) NOT NULL,/* more columns here */
    [VBTerminator] [varchar](1) NOT NULL
) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IX_dbo_CustDataMaster_CustNum] ON dbo.CustDataMaster
(
    [CustNum] ASC
)WITH (PAD_INDEX = OFF,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

我在这两个表中都没有聚簇索引,只有一个非聚簇索引.

忽略数据类型与存储的数据类型不完全匹配的事实.这些字段是IBM AS / 400 DB2数据库的备份,它们是兼容的数据类型. (我必须能够使用完全相同的查询来查询此备份数据库,并获得完全相同的结果.)

此数据仅用于SELECT语句.除了备份应用程序从AS / 400复制数据时,我不会对其执行任何INSERT / UPDATE / DELETE语句.

解决方法

通常,如果SQL Server认为使用索引比直接使用基础表更方便,则SQL Server将使用索引.

基于成本的优化器似乎认为实际使用该索引会更昂贵.您可能会看到它使用索引而不是SELECT *,您只需选择SELECT T1Col1.

SELECT *时,您告诉SQL Server返回表中的所有列.要返回这些列,SQL Server必须从表本身(聚簇索引或堆)中读取与WHERE语句条件匹配的行的页面. SQL Server可能认为从表中获取其余列所需的读取量意味着它也可以直接扫描表.查看实际查询和查询使用的实际执行计划会很有用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读