sql - 为什么当我加入另一个表时逻辑读取会增加
问题描述
我一直在查看我们数据库中一些长时间运行的查询,目的是减少花费的时间。我正在查看的一件事是每个表、每个查询的逻辑读取次数,但我不确定为什么某些表的逻辑读取如此之高。
我可以展示一个非常基本的示例来重现“问题”,而不是发布长查询。我创建了这个查询:
SELECT p.Id
FROM
Products p
INNER JOIN StaffMembers sm ON p.CreatedById = sm.Id AND sm.IsDeleted = 0
WHERE p.DateCreated > '01-MAY-2021'
该StaffMembers
表的逻辑读取数为 6,返回的行数为 219
如果我稍微更改查询,以引入另一个表:
SELECT p.Id
FROM
Products p
INNER JOIN StaffMembers sm ON p.CreatedById = sm.Id AND sm.IsDeleted = 0
INNER JOIN ProductCategories pc ON p.Id = pc.ProductId AND pc.IsDeleted = 0
WHERE p.DateCreated > '01-MAY-2021'
现在的逻辑读取数StaffMembers
为 13,行数仍为 219。
查询返回的记录数完全相同。从执行计划来看,索引扫描所用的StaffMembers
完全一样。那么,为什么第二个查询的逻辑读取更高呢?
解决方案
在此处添加更多细节,这对于评论来说太长了。
在第二个查询的执行计划中,选择select
运算符。查看属性(或查看鼠标悬停弹出窗口)并注意估计的子树成本为 8.1;这是 SQL Server 对涉及多少工作的猜测,它高于默认阈值 5,因此(通常)这意味着它将考虑并行计划;并非总是如此,查询的某些元素可以强制执行串行计划,但通常情况下。
在两个表之间选择了一种merge
连接方法,并且操作员的输入需要排序输入,因此工作分配给多个线程。
如果您选择索引扫描运算符StaffMembers
并查看属性,请注意下面actual I/O statistics
是您观察到的逻辑读取以及它们如何分布在所有线程中。
鉴于查询在 <1 秒内完成,因此可能不需要并行,只是因为并行性的成本阈值设置得太低(这是 SQL Server 老化默认值之一,应该真正修改)。推荐值介于 40-60 之间。
当然,查询是对 和 进行表扫描,Products
并且ProductCategories
一些额外的支持索引将是有益的,并有助于通过更好的统计数据来提高估计成本。
推荐阅读
- javascript - 如何在工具提示消息中包含图标
- android - 在清单中声明全屏和沉浸式应用
- javascript - 当我尝试在 chrome 中创建书签时,控制台中出现错误“浏览器未定义”
- python - 如何对 seaborn 的 lmplot 进行 funcanimation
- nginx - 如何在 https NGINX 中将非 www 重定向到 www
- mysql - 除以 2 行表格并得出百分比
- sql-server - 使用 PowerShell 脚本创建具有混合模式身份验证的 SQL VM
- spring - Jdbc 模板和 Spring 的 keyHolder 的 Mockito 测试用例
- javascript - 将 React 组件转换为单个 js 文件以将其与空白 html 集成
- javascript - 反应:我对减速器的编辑状态有一些错误