有人可以查看查詢并建議任何改進或優化查詢,以便查詢運行得更快。
所以基本上,我有 2 個表調查和調查邀請。
表格調查的樣本資料
CREATE TABLE dbo.Survey
(
createdate date,
emailinvite char(4),
phoneinvite char(4),
smsinvite char(4),
surveyid int
);
INSERT dbo.Survey VALUES
('20220201','12ab','12bc', null ,1),
('20220210','23be','45hg','45tr',2),
('20220220','65hg', null ,'89kj',3);
Table SurveyInvite的樣本資料
CREATE TABLE dbo.SurveyInvite
(
sentdate date,
id char(4)
);
INSERT dbo.SurveyInvite VALUES
('20220201','12ab'),
('20220205','12bc'),
('20220210','23be'),
('20220214','45hg'),
('20220218','45tr'),
('20220220','65hg'),
('20220224','89kj');
輸出應該是
| 型別 | 發送日期 | 邀請ID | 調查ID |
|---|---|---|---|
| 電子郵件 | 2022-02-01 | 12ab | 1 |
| 電子郵件 | 2022-02-10 | 23be | 2 |
| 電子郵件 | 2022-02-20 | 65hg | 3 |
| 電話 | 2022-02-05 | 公元前12年 | 1 |
| 電話 | 2022-02-14 | 45hg | 2 |
| 短信 | 2022-02-18 | 45tr | 2 |
| 短信 | 2022-02-24 | 89kj | 3 |
所以基本上,我必須針對每種型別(電子郵件、電話、短信)從 SurveyInvite 表中獲取發送日期。
調查表應在電子郵件、電話和短信上不進行透視,以將列轉換為行。
這是我的查詢
SELECT 'Email' as Type,esi.sentdate,emailinvite as inviteid,s.surveyid
FROM Survey s
INNER JOIN SurveyInvite esi on s.emailinvite=esi.id
UNION
SELECT 'SMS' as Type,ssi.sentdate,smsinvite as inviteid,s.surveyid
FROM Survey s
INNER JOIN SurveyInvite ssi on s.smsinvite=ssi.id
UNION
SELECT 'Phone' as Type,psi.sentdate,phoneinvite as inviteid,s.surveyid
FROM Survey s
INNER JOIN SurveyInvite psi on s.phoneinvite=psi.id
如果這樣可以使查詢更快,請建議其他撰寫查詢的方法。我仍在嘗試使用 UNPIVOT、左連接、CTE 來避免使用 UNION。
示例設定在這里
uj5u.com熱心網友回復:
您不需要查詢表三次,您只需取消透視即可。最簡單的方法是使用CROSS APPLY (VALUES
SELECT
v.Type,
ssi.sentdate,
v.inviteid,
s.surveyid
FROM Survey s
CROSS APPLY (VALUES
('Email', s.emailinvite),
('Phone', s.phoneinvite),
('SMS', s.smsinvite)
) v (Type, inviteid)
INNER JOIN SurveyInvite ssi on v.inviteid = ssi.id;
我建議您首先考慮通過將未透視的資料存盤在單獨的表中來規范化您的資料庫。
uj5u.com熱心網友回復:
另一種方式(同樣關鍵是只讀取一個表一次而不是三次):
SELECT i.sentdate,
[Type] = REPLACE(u.Types, 'invite', ''),
inviteid = u.id,
u.surveyid
FROM dbo.Survey AS s
UNPIVOT (Id FOR Types IN
(emailinvite, phoneinvite, smsinvite)) AS u
INNER JOIN dbo.SurveyInvite AS i ON u.Id = i.id;
從db<>fiddle可以看出,這消除了 6 次表掃描中的 4 次,并且還消除了昂貴的不同排序。
uj5u.com熱心網友回復:
我假設您已正確設定主鍵和外鍵。在外鍵上有索引也可能有益。請參閱:每個 SQL Server 外鍵都應該有一個匹配的索引嗎?.
與這些性能問題一樣。只有對不同的變體進行基準測驗才能告訴您哪一個是最快的。對于不同的資料集,相同的查詢可以執行非常不同的操作。
一種可能性是使用連接并將查詢基于SurveyInvite:
SELECT
I.sentdate,
CASE WHEN SE.id IS NOT NULL THEN 'Email'
WHEN SP.id IS NOT NULL THEN 'Phone'
ELSE 'SMS'
END AS Type,
I.id AS inviteid,
CASE WHEN SE.id IS NOT NULL THEN SE.surveyid
WHEN SP.id IS NOT NULL THEN SP.surveyid
ELSE SS.surveyid
END AS surveyid
FROM
SurveyInvite I
LEFT JOIN Survey SE
ON I.emailinvite = SE.id
LEFT JOIN Survey SP
ON I.phoneinvite = SP.id
LEFT JOIN Survey SS
ON I.smsinvite = SS.id
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/432419.html
上一篇:如何使用特定型別的連字符查詢AzureSQL服務器?
下一篇:有沒有辦法計算列中值的數量?
