[英]T-SQL | Better alternative to WHERE NOT EXISTS
我有以下查詢:
INSERT INTO [Table A] ([student_name], [class_id],[contact_detail], [birth_date],[note_average])
SELECT [student_name] = case when CHARINDEX('.', [student_name])>0 then LEFT([student_name],CHARINDEX('.', [student_name])-1)
else [student_name] end
,[class_id]
,case when reverse(SUBSTRING(REVERSE([contact_detail]),1,CHARINDEX(':', REVERSE([contact_detail])))) like ':'
then ([contact_detail] + '|')
else [contact_detail]
end as [contact_detail]
,[birth_date]
,CAST([note_average] AS decimal(13,2)) as [note_average]
,GETDATE()
FROM [Table A]
WHERE CAST([birth_date] AS DATE) <= CAST(GETDATE() AS DATE)
AND LEN([student_name]) >= 5
AND NOT EXISTS
(
SELECT [student_name]
,[class_id]
,[contact_detail]
,[birth_date]
FROM [Table A] a
WHERE '%' + ods.[student_name] + '%' LIKE a.[student_name]
AND '%' + ods.[class_id] + '%' LIKE a.[class_id]
AND '%' + ods.[contact_detail] + '%' LIKE a.[contact_detail]
AND ods.[birth_date] = a.[birth_date]
)
GO
我不想插入重復的值,並且我的表中沒有鍵。 我的問題是:此查詢需要大量時間來插入新值。 我正在嘗試插入1000000行。
我有哪些選擇?
非常感謝!
假設您確實想在完全重復的匹配項上進行匹配,請嘗試如下操作:
INSERT INTO [Table A] ([student_name], [os_name], [class_id],[contact_detail], [birth_date],[note_average])
SELECT ods.[student_name] = case when CHARINDEX('.', ods.[student_name])>0 then LEFT(ods.[student_name],CHARINDEX('.', ods.[student_name])-1)
else ods.[student_name] end
,ods.[class_id]
,case when reverse(SUBSTRING(REVERSE(ods.[contact_detail]),1,CHARINDEX(':', REVERSE(ods.[contact_detail])))) like ':'
then (ods.[contact_detail] + '|')
else ods.[contact_detail]
end as [contact_detail]
,ods.[birth_date]
,CAST(ods.[note_average] AS decimal(13,2)) as ods.[note_average]
,GETDATE()
FROM [Table A] ods
OUTER JOIN [Table A] a ON ods.[student_name] = a.[student_name]
AND ods.[os_name] = a.[os_name]
AND ods.[class_id] = a.[class_id]
AND ods.[contact_detail] = a.[contact_detail]
AND ods.[birth_date] = a.[birth_date]
WHERE CAST(ods.[birth_date] AS DATE) <= CAST(GETDATE() AS DATE)
AND LEN(ods.[student_name]) >= 5
-- Only include when no matching duplicate is found.
AND a.[student_name] IS NULL
如果需要的話,可以堅持使用子查詢和NOT EXISTS,這也很好,但是可以使用SELECT 0或類似的方法來代替選擇所有這些列,這不是必需的。 我相信,將比較從LIKE更改為=將為您提供所需的結果,並在必要時使查詢可以使用索引進行優化。
AND NOT EXISTS
(
SELECT 0
FROM [Table A] a
WHERE ods.[student_name] = a.[student_name]
AND ods.[os_name] = a.[os_name]
AND ods.[class_id] = a.[class_id]
AND ods.[contact_detail] = a.[contact_detail]
AND ods.[birth_date] = a.[birth_date]
)
一旦該查詢正常運行,然后就可以在需要更好的性能時考慮添加索引。 您也許可以僅在[birth_date]或[student_name]上添加索引以獲得可接受的查詢性能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.