我有一個表,ProcessQueueLog其中包含一個分隔欄位值,我需要將其拆分并連接到另一個表。我有一份作業宣告,但似乎很慢。有人可以建議更好的方法嗎?
fn_SplitString是由一位已故的開發人員在內部撰寫的。它回傳 part1 和 part2,是任何拆分字串函式的典型特征。
SELECT pql.*, cl.ShortNote
FROM Automation.ProcessQueueLog pql
INNER JOIN dbo.CLog cl
ON cl.Conversation_ID = CAST((SELECT Part1 FROM dbo.fn_SplitString (pql.QueuedRecordId, '-')) AS INT)
AND cl.Memo_ID = CAST((SELECT Part2 FROM dbo.fn_SplitString (pql.QueuedRecordId, '-')) AS INT);
uj5u.com熱心網友回復:
擴展我的評論
SELECT pql.*
, cl.ShortNote
FROM Automation.ProcessQueueLog pql
CROSS APPLY dbo.fn_SplitString(pql.QueuedRecordId, '-') SS
INNER JOIN dbo.CLog cl
ON cl.Conversation_ID = SS.Part1
AND cl.Memo_ID = SS.Part2;
我懷疑你的 split 函式有一個 LOOP。如果是這樣,還有更多高效的方法
uj5u.com熱心網友回復:
另一種消除(幾乎肯定是低效的)函式的方法,如果我們只是從字串中分解少量的、已知的和固定數量的元素(拆分函式,即使是非常低效的函式,當數字為輸入元素的數量未知):
;WITH ql(q,p) AS
(
SELECT QueuedRecordId, CHARINDEX('-', QueuedRecordId) -- , other cols
FROM Automation.ProcessQueueLog
WHERE QueuedRecordId LIKE '%[0-9]-[0-9]%'
)
SELECT ql.*, cl.ShortNote
FROM ql CROSS APPLY
(
VALUES
(
TRY_CONVERT(int,LEFT(q,p-1)),
TRY_CONVERT(int,SUBSTRING(q,p 1,32))
)
) AS q2(l,r)
INNER JOIN dbo.CLog AS cl
ON cl.Conversation_ID = q2.l
AND cl.Memo_ID = q2.r;
- 示例資料庫<>小提琴
為了保證-與 CTE 內部過濾器中缺少的無效值絕緣,您可以將第一行q2(產生l“左側”的運算式)更改為稍微難看一點:
TRY_CONVERT(int,LEFT(q,COALESCE(NULLIF(p,0),1)-1)),
(盡管該修復假定0不能代表有效 ID。)
如果您使用的是 SQL Server 2016 或更高版本(對于指定您需要支持的版本總是有用的),另一種可能性是OPENJSON用于可靠的、有序的、基于集合的拆分,然后使用PIVOT:
;WITH ql AS
(
SELECT ql.QueuedRecordId, j.[key], j.[value]
FROM Automation.ProcessQueueLog AS ql CROSS APPLY
OPENJSON ('["' REPLACE(ql.QueuedRecordId,'-','","') '"]"') AS j
)
SELECT p.QueuedRecordId, cl.ShortNote
FROM ql PIVOT (MAX([value]) FOR [key] IN ([0],[1])) AS p
INNER JOIN dbo.CLog AS cl
ON cl.Conversation_ID = p.[0]
AND cl.Memo_ID = p.[1];
- 示例資料庫<>小提琴
但是,如果任何緩慢是由于您忘記提及的鏈接服務器連接(怎么可能不是?),您可能會追趕您的尾巴。
我的建議:使用表的本地副本獲得最有效的查詢(幾乎肯定不會涉及多陳述句表值函式)CLog(將實際的執行后計劃發布到您認為應該有效的PasteThePlan.com但不是),然后分別對網路連接進行故障排除。就我們所知,緩慢可能是從明顯缺失的索引到可以串通的網路連接。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/371558.html
標籤:sql sql-server 查询语句
