SQL Server 索引的性能

4 index sql-server

我想在运行相同查询时查看索引列与非索引列之间的性能差异。

我创建的表 (FileCollection) 非常简单,有以下 3 列

  1. Id (int) - 自动生成数字的主键。
  2. FileName ( nvarchar(MAX))- 包含文件名。
  3. 说明 ( nvarchar(MAX))- 包含文件的说明。

我正在使用的查询是:

SELECT * FROM FileCollection WHERE FileName='readme.txt'
Run Code Online (Sandbox Code Playgroud)

我已经用超过 10 万条记录填充了数据库。使用该SQL Server Profiler工具,我最初在 FileName 列上没有索引的情况下运行查询,并在将索引添加到 FileName 列时再次运行。但是,我看不出任何性能差异。

两个测试的平均值大致相同:CPU:500 读取:13,000 写入:0 持续时间:200

谁能帮我弄清楚为什么?我认为 10 万条记录足以显示一些差异,但我需要更多记录吗?

TIA

编辑:我现在已将 FileName 列更改为 nvarchar(255) 但问题仍然存在。顺便说一句,我使用的是 SQL Server 2008 R2。

JNK*_*JNK 8

我很确定你会遗漏一些东西:

(n)varchar(max) 字段不能被索引

来自 MSDN:

大对象 (LOB) 数据类型 ntext、text、varchar(max)、nvarchar(max)、varbinary(max)、xml 或 image 的列不能指定为索引的键列。此外,视图定义不能包含 ntext、text 或 image 列,即使它们未在 CREATE INDEX 语句中引用。

尝试创建索引时是否遇到错误?

您的两个查询都是相同的,因为它们是相同的 - 由于您无法索引该字段,因此它们都在创建表扫描。


mar*_*c_s 6

根据您的服务器拥有的 RAM 量,它可能只是将整个表读入内存并将其保存在那里 - 因此您的第一个查询将加载它,并且任何后续查询将只对加载到内存中的那些页面进行操作。

要获得任何有意义的数据,您需要在每次运行查询之前刷新缓存!(运行DBCC FREEPROCCACHEDBCC DROPCLEANBUFFERS任何查询执行之前!)

我试着用100'000虚拟文件名和几乎相同的表结构的情况下(我改变FileNameVARCHAR(260))。


无索引:

表“测试文件”。扫描计数 1,逻辑读取 2137,物理读取 5,预读读取 2136,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

查询子树成本 1.68884


在文件名上使用非聚集索引:

表“测试文件”。扫描计数 1,逻辑读 6,物理读 4,预读 0,lob 逻辑读 0,lob 物理读 0,lob 预读 0。

查询子树成本 0.0065704


这是通过以下语句完成的:

DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS 

SET STATISTICS IO ON

SELECT * 
FROM testfiles
WHERE FileName = 'File-D8584B44-518F-428A-86A1-7836E0B60502'
Run Code Online (Sandbox Code Playgroud)