向查询中添加WHERE子句会使查询速度变慢-即使列已建立索引

时间:2019-06-24 18:04:24

标签: sql sql-server indexing

因此,用户表有4000万行。如果我没有WHERE子句,下面的查询将足够快地运行(不到1秒)  如果将WHERE子句放在查询中,则大约需要10分钟才能返回结果集。  我在UserType列上添加了一个索引,但是由于某种原因,它似乎并未影响响应时间

  CREATE INDEX idx_users_user_type ON Users (UserType);

查询:

SELECT  TOP 100
        *
FROM Users u
    INNER JOIN Company c ON c.ID = u.CompanyID
    INNER JOIN Location l ON l.ID = u.LocationId
WHERE
    u.UserType = 'manager'

UserType只有3个值:

manager
employee
temp

如果可能的话,我不想将列更改为INT值,因为ETL流程会将数据导入到现在很难更改的表中。

2 个答案:

答案 0 :(得分:5)

首先,您应该在不使用TOP的情况下使用ORDER BY来阅读this article。简短的版本是您不能保证每次运行的结果都一样,除非您有ORDER BY

由于SQL Server只需对 first 100行执行TABLE SCAN,因此第一个查询运行很快。简单。现在,您添加了WHERE子句... SQL Server必须找到该谓词为true的所有行。当然,您有一个索引,这可以有所帮助。 SQL Server将(或可能)使用该索引,但是如果使用了该索引,则它将必须进行键查找来检索其余的列(因为您SELECT *)。因此,它需要做更多的工作。很有可能甚至没有使用索引,因为SQL Server可以决定仅执行TABLE SCAN来检查每一行的谓词,而不是进行键查找,这样更快。当然,这意味着您必须读取4000万行(检查表的大小...这需要进入内存。我敢打赌它已分页到磁盘上,甚至是spilling to TEMPDB)。

因此,它当然会变慢...您正在针对4000万行检查条件,而不是提取 random TOP 100。如果您需要有关所有DDL(创建表,创建索引)语句的进一步帮助,we need the execution plans at a minimum

要探索的其他选项是:

答案 1 :(得分:1)

您可以添加索引:

CREATE INDEX idx_users_user_type_company_id_location_id 
          ON Users (CompanyId, LocationId,UserType);
相关问题