Количество логических операций чтения увеличивается с одним дополнительным внутренним соединением

У меня есть две таблицы, которые выглядят почти одинаково. Когда я выбираю любой из них, мои логические чтения составляют около 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

Только AccountBalances

Дополнительная информация

Результат запроса - 170460 строк, а общее логическое чтение - 376.000. Но если я использую "top 170000" в своем запросе, то общее логическое чтение составит только 44.000. Статистика IO выглядит так:

И план выполнения выглядит так

1 ответ

Я нашел решение для моей проблемы.

1. AccountBalances содержит сальдо в учетной валюте банка, которая является DKK, а AccountBalancesInAccountCurrency содержит сальдо в валюте счета, а также в DKK. Большинство валют является DKK и существует в обеих таблицах. Поэтому я удалил все остатки DKK из AccountBalancesInAccountCurrency и сделал левое соединение с этой таблицей.

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 выглядит так:

и мой план выполнения, как это.

Спасибо за все комментарии, которые привели меня на моем пути.

Счастливых праздников!