查询未执行索引查找或扫描

sur*_*ain 2 sql sql-server indexing rdbms sql-server-2008

我对Indexes相当新.我有下表[FORUM1]

    [msg_id] [int] IDENTITY(1,1) NOT NULL,
    [cat_id] [int] NULL,
    [msg_title] [nvarchar](255) NULL
Run Code Online (Sandbox Code Playgroud)

并创建了一个非聚集索引

CREATE NONCLUSTERED INDEX catindex ON forum1(cat_id)
Run Code Online (Sandbox Code Playgroud)

现在当我运行这个简单的查询时,我可以看到索引没有被使用

SELECT msg_title FROM forum1 where cat_id=4
Run Code Online (Sandbox Code Playgroud)

如果我创建CI并包含MSG_TITLE字段,则仅调用索引.但问题是我必须在实际的表上运行更多类似的查询,例如date = something,userid = 20,status = 1.因此,在每个索引中包含列对我来说都不好.

执行计划截图

mar*_*c_s 6

msg_title不包含在索引- >在非聚集索引中找到需要一个任意值键查找到实际的数据页,这是一个昂贵的操作 -因此,因此,最有可能的,表扫描更快.另外:"表扫描"表示你有一个堆 - 一个没有聚簇索引的表 - 这是一件坏事(大部分时间)开始.为什么你没有聚集索引?

您可以通过在索引中包含以下内容来解决此问题msg_title:

CREATE NONCLUSTERED INDEX catindex 
ON forum1(cat_id) INCLUDE(msg_title)
Run Code Online (Sandbox Code Playgroud)

现在,我很确定,SQL Server将使用该索引(因为它可以在索引结构中找到查询所需的所有数据 - 该索引被称为覆盖索引).这里的好处是:额外的列只包含在索引的叶级中,因此它使索引只有最小的大小.然而,它可能导致索引被更频繁地使用.非常值得!

  • @surajjain - 不,现在优化器决定使用表扫描而不是索引搜索或索引扫描的事实是你当前的选择(`cat_id = 4`),它需要做的嵌套循环选择的行将比表扫描执行得最差.如果你使用更具选择性的过滤器(即返回更少行的cat_id的值),那么它最有可能使用索引(索引不是覆盖索引) (2认同)