逻辑读取数量随着一个额外的内部连接而爆炸

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);

enter image description here

当我只加入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);

enter image description here

当我只加入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]

我究竟做错了什么?

执行计划

Both Tables enter image description here

AccountBalancesInAccountCurrency Only enter image description here

AccountBalances Only enter image description here

额外信息

查询结果为170460行,总逻辑读取为376.000。但如果我在查询中使用“top 170000”,那么逻辑读取总数仅为44.000。统计IO看起来像这样:enter image description here

And the execution plan looks like this enter image description here

答案

我找到了解决问题的方法。

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
)

现在我的IO看起来像这样:enter image description here

and my execution plan like this

感谢所有引导我前进的评论。

节日快乐!

以上是关于逻辑读取数量随着一个额外的内部连接而爆炸的主要内容,如果未能解决你的问题,请参考以下文章

磁盘配置

ViewPager 片段随着时间的推移而被破坏?

字节输入流----ByteArrayInputStream

我怎样才能使它如此这个java程序将读取二进制文件的其余部分,而不是添加额外的空格?

导航项目已选中,传递额外信息

极简逻辑表达式的设计和查询