使用索引时的随机读
嗯,关于随机读我现在也有些迷糊,只是大概的知道发生随即读时即便需要的数据就存在同一页上,也会发生多次读取,而不是一次拿到整页数据后进行筛选。当进行where in查找或发生书签查找时,一定会使用随机读
首先我们看看聚集索引的随即读表现
--创建聚集索引IX_UserID CREATE UNIQUE CLUSTERED INDEX IX_UserID ON dbo.Users(UserID) |
执行如下查询,可以发现在聚集索引上面使用where in时不管有没有找到记录都会进行聚集索引查找,而且查找次数固定为where in里面的条件数*索引级数,不知道为什么明明索引扫描有着更高的效率,查询优化器还是选择聚集索引查找,有知道的朋友还请告知下哈
--这个聚集索引扫描,返回记录7条,逻辑读2次 SELECT * FROM dbo.Users --这个聚集索引查找,返回记录3条,逻辑读2次 SELECT * FROM dbo.Users WHERE UserID<=2 --这个聚集索引查找,返回记录3条,逻辑读6次 SELECT * FROM dbo.Users WHERE UserID IN(1,2) --这个聚集索引查找,返回记录0条,逻辑读6次 SELECT * FROM dbo.Users WHERE UserID IN(10,20,22) |
(7 行受影响) 表 'Users'。扫描计数 1,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
(3 行受影响) 表 'Users'。扫描计数 1,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
(3 行受影响) 表 'Users'。扫描计数 3,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响)
(0 行受影响) 表 'Users'。扫描计数 3,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
(1 行受影响) |
我们再来看下非聚集索引的随机读,当然我这里为了演示特意使用了索引提示,实际应用中没事千万别加索引提示,当使用非聚集索引时查询优化器发现使用索引后效率更低时会放弃索引转为使用表扫描,我们这个例子中若去掉索引提示的话使用表扫描仅需要2次逻辑读就可以完成查询,这里仅仅是为了演示
--非聚集索引查找,返回记录2,逻辑读2 SELECT UserID,UserName FROM dbo.Users WITH(INDEX(IX_UserName))WHERE UserName LIKE 'J%' --非聚集索引查找,返回记录2,逻辑读4 SELECT UserID,UserName FROM dbo.Users WITH(INDEX(IX_UserName))WHERE UserName IN('Bob','Jack')
--非聚集索引查找+书签查找,返回记录2,逻辑读6 SELECT UserID,UserName,CreateTime FROM dbo.Users WITH(INDEX(IX_UserName))WHERE UserName LIKE 'J%'
--非聚集索引查找+书签查找,返回记录0,逻辑读2(索引查找2*1+书签查找2*0) SELECT UserID,UserName,CreateTime FROM dbo.Users WITH(INDEX(IX_UserName))WHERE UserName IN('Rabbit') --非聚集索引查找+书签查找,返回记录1,逻辑读4(索引查找2*1+书签查找2*1) SELECT UserID,UserName,CreateTime FROM dbo.Users WITH(INDEX(IX_UserName))WHERE UserName IN('Bob') --非聚集索引查找+书签查找,返回记录2,逻辑读8(索引查找2*2+书签查找2*2) SELECT UserID,UserName,CreateTime FROM dbo.Users WITH(INDEX(IX_UserName))WHERE UserName IN('Bob','Jack') |