我正在嘗試查找擁有(或共同擁有)帳戶和帳號的客戶串列。
我們的 CLIENT 表包含我們的客戶資料,用 a 標識clientId(表還包含人口統計和聯系方式)。
我們的 ACCOUNTS 表包含帳戶資訊,其中 aclientId可以存在于 1 或 5 列中(一個帳戶最多可以有 5 個共同所有者)。
我的代碼看起來像這樣,但速度非常慢。這是正確的方法嗎?還有其他更便宜的方法嗎?
SELECT
c.*, aa.accountNo
FROM
client AS c, accounts AS aa
WHERE
EXISTS (SELECT 1
FROM accounts AS a
WHERE CAST(a.Account_Date AS Date) >= '2010-11-15'
AND CAST(a.Account_Date AS Date) <= '2017-04-24'
AND c.clientId IN (a.Owner1, a.Owner2, a.Owner3, a.Owner4, a.Owner5))
uj5u.com熱心網友回復:
您的查詢會展開資料集并掃描帳戶兩次。此外,我們不應該強制轉換列側以適應日期范圍,現在有一種方法是有益的(它可能并不總是會導致掃描,但它仍然不是很好)。嘗試:
SELECT c.*, a.accountNo
FROM dbo.accounts AS a
CROSS APPLY
(
VALUES(Owner1),(Owner2),(Owner3),(Owner4),(Owner5)
) AS ac(clientId)
INNER JOIN dbo.client AS c
ON c.clientId = ac.clientId
WHERE a.Account_Date >= '20101115'
AND a.Account_Date < '20170425';
- 示例db<>fiddle
uj5u.com熱心網友回復:
您的主要問題是缺乏標準化。您不應該有五Owner列。相反,您應該有一個單獨的AccountOwner. 然后你可以簡單地加入它。
這實際上是您從@AaronBetrand 的回答中得到的,除了那個不能被索引,因為它是虛擬的。
另請注意:
- 無需
accounts在子查詢中再次訪問。 - 始終使用顯式連接語法,而不是隱式
,語法。 - 切勿為了過濾或加入列而投射列。總是轉換常量。在這種情況下,您甚至不需要投射它們。
SELECT
c.*,
a.accountNo
FROM Client AS c
JOIN AccountOwner AS ao ON ao.OwnerId = c.ClientId
JOIN Accounts AS a
ON a.AccountNo = ao.AccountNo
AND a.Account_Date >= '20101115'
AND a.Account_Date < '20170425';
要使此查詢有效地作業,您將需要以下索引
Account (Account_Date, AccountNo)
AccountOwner (AccountNo, OwnerId)
Client (ClientId) INCLUDE (OtherColumns)
一組替代索引可能證明是更好的訪問策略(您需要測驗)
Account (AccountNo) INCLUDE (Account_Date)
AccountOwner (OwnerId, AccountNo)
Client (ClientId) INCLUDE (OtherColumns)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/439783.html
