coo*_*eze 1 sql sql-server indexing
因此,用户表有4000万行。如果没有WHERE子句,下面的查询将足够快地运行(不到1秒)。如果在查询中放入WHERE子句,则大约需要10分钟才能返回结果集。我在UserType列上添加了索引,但是由于某种原因,它似乎并未影响响应时间
CREATE INDEX idx_users_user_type ON Users (UserType);
Run Code Online (Sandbox Code Playgroud)
查询:
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'
Run Code Online (Sandbox Code Playgroud)
UserType只有3个值:
manager
employee
temp
Run Code Online (Sandbox Code Playgroud)
我不希望将列更改为INT值,因为ETL流程会将数据导入到现在很难更改的表中。
首先,您应该阅读有关不使用的文章。简短的版本是您不能保证每次运行的结果都一样,除非您有。TOPORDER BYORDER BY
第一个查询运行很快,因为SQL Server只需对前 100行执行TABLE SCAN 。简单。现在添加一个WHERE子句... SQL Server必须找到该谓词为true的所有行。当然,您有一个索引,这可以有所帮助。SQL Server将(或可能)使用该索引,但是如果使用了该索引,则它将必须进行键查找来检索其余的列(因为您SELECT *)。因此,它需要做更多的工作。很有可能甚至没有使用该索引,因为SQL Server可以决定仅执行TABLE SCAN来检查每一行的谓词,而不是进行键查找,这样更快。当然,这意味着您必须读取4000万行(检查表的大小...这需要进入内存。我敢打赌它已分页到磁盘上,甚至溢出到TEMPDB)。
因此,这当然会更慢...您正在针对4000万行检查条件,而不是随机抽取 TOP 100。如果您需要进一步的帮助,我们至少需要具有所有DDL(创建表,创建索引)语句的执行计划。
其他可供选择的选项包括: