逻辑读取数量随着一个额外的内部连接而爆炸
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逻辑读取数量随着一个额外的内部连接而爆炸相关的知识,希望对你有一定的参考价值。
我有两张看起来几乎相同的桌子。当我从其中任何一个中选择时,我的逻辑读取大约为8.000-10.000次读取。但当我内心加入它们时,我得到了大约380.000个逻辑读取。
我使用MS SQL 2012。
我遇到问题的查询如下所示:
SELECT ac.ID AS AccountID
,ab.Balance
,abc.BalanceInAccountCurrency
FROM dbo.Dates d
INNER JOIN dbo.Accounts ac ON d.[Date] BETWEEN ac.CreationDate AND ac.ClosureDate
INNER JOIN dbo.AccountBalances ab ON ab.AccountID = ac.ID AND d.[Date] BETWEEN ab.CreationDate AND ab.ClosureDate
INNER JOIN dbo.AccountBalancesInAccountCurrency abc ON abc.AccountID = ac.ID AND d.[Date] BETWEEN abc.CreationDate AND abc.ClosureDate
WHERE d.[Date] = DATEFROMPARTS(2017,06,20);
当我只加入AccountBalances时:
SELECT ac.ID AS AccountID
,ab.Balance
FROM dbo.Dates d
INNER JOIN dbo.Accounts ac ON d.[Date] BETWEEN ac.CreationDate AND ac.ClosureDate
INNER JOIN dbo.AccountBalances ab ON ab.AccountID = ac.ID AND d.[Date] BETWEEN ab.CreationDate AND ab.ClosureDate
WHERE d.[Date] = DATEFROMPARTS(2017,06,20);
当我只加入AccountBalancesInAccountCurrency时,我得到了类似的结果。
我的主键/聚簇索引在两个表上都是这样的:
ALTER TABLE [dbo].[AccountBalances] ADD CONSTRAINT [PK_AccountBalances] PRIMARY KEY CLUSTERED
(
ClosureDate DESC,
CreationDate DESC,
AccountID ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
我究竟做错了什么?
执行计划
AccountBalancesInAccountCurrency Only
额外信息
查询结果为170460行,总逻辑读取为376.000。但如果我在查询中使用“top 170000”,那么逻辑读取总数仅为44.000。统计IO看起来像这样:
我找到了解决问题的方法。
1. AccountBalances包含银行会计货币的余额,即DKK,AccountBalancesInAccountCurrency包含帐户货币和DKK的余额。大多数货币都是DKK,存在于两个表中。因此,我从AccountBalancesInAccountCurrency中删除了所有DKK余额,并对该表进行了左连接。
2.我还更改了AccountBalancesInAccountCurrency上的主键:
ALTER TABLE [dbo].[AccountBalances] ADD CONSTRAINT [PK_AccountBalances]
PRIMARY KEY CLUSTERED
(
ClosureDate DESC,
CreationDate DESC,
AccountID ASC
)
至:
ALTER TABLE [dbo].[AccountBalancesInAccountCurrency] ADD CONSTRAINT
[PK_AccountBalancesInAccountCurrency] PRIMARY KEY CLUSTERED
(
[AccountID] ASC,
[ClosureDate] DESC
)
and my execution plan like this。
感谢所有引导我前进的评论。
节日快乐!
以上是关于逻辑读取数量随着一个额外的内部连接而爆炸的主要内容,如果未能解决你的问题,请参考以下文章