簡體   English   中英

如何在大varchar字段上使用JOIN加速SQL查詢,並且不存在

[英]How to speed up SQL query with JOIN on large varchar field and a NOT EXISTS

我有這個查詢,要永遠運行。 該表包含約700萬行。 我正在使用它進行的所有其他操作(這是一個“臨時”永久表)都相對較快(一個小時左右)運行,而此UPDATE屬於該操作花了7個小時! 我們有SQL Server 2014。

DOINVARCHAR(72)並且具有非唯一的CLUSTERED索引。 AffiliationsVARCHAR(8000) 我真的不允許更改這些數據類型。 Affiliations有一個包含索引。 由於該字段太大,因此我們無法執行“常規”索引。

CREATE NONCLUSTERED INDEX IX_Affiliations 
    ON TempSourceTable (DOI) INCLUDE (Affiliations);

如果DOI所有記錄在其“ Affiliations列中都具有相同的值,則下面的語句將位字段設置為1。 該表每個DOI值具有多個記錄,我們想知道對於具有相同DOI所有記錄,“ Affiliations列是否相同。

有什么辦法可以通過編寫不同的查詢,不同的索引來加快此速度,還是我會出錯呢?

UPDATE S
SET AffiliationsSameForAllDOI = 1
FROM TempSourceTable S
WHERE NOT EXISTS (SELECT 1 
                  FROM TempSourceTable S2 
                  WHERE S2.DOI = S.DOI 
                    AND S2.Affiliations <> S.Affiliations)

這是另一種方式

SUB-QUERY版本

UPDATE TempSourceTable
SET    AffiliationsSameForAllDOI = 1
WHERE  doi IN (SELECT doi
               FROM   TempSourceTable S
               GROUP  BY DOI
               HAVING COUNT(DISTINCT Affiliations) = 1) 

EXISTS版本

UPDATE TempSourceTable S
SET    AffiliationsSameForAllDOI = 1
WHERE EXISTS  (SELECT 1
               FROM   TempSourceTable S1
               Where s1.DOI = s.DOI
               HAVING COUNT(DISTINCT Affiliations) = 1) 

INNER JOIN版本

UPDATE S 
SET    AffiliationsSameForAllDOI = 1
FROM TempSourceTable S
INNER JOIN (SELECT doi
            FROM   TempSourceTable 
            GROUP  BY DOI
            HAVING COUNT(DISTINCT Affiliations) = 1) S1
        ON S.DOI = S1.DOI
update TempSourceTable
set AffiliationsSameForAllDOI = 1
where DOI in (
    select DOI
    from TempSourceTable
    group by DOI
    having count(distinct Affiliations) = 1
)

根據您的數據看起來如何,可能會創建一個計算出的列,以去除Affiliations的前16個字符,或者僅使用checksum()然后在該列上建立索引,從而提高性能。 也許看起來像這樣:

update TempSourceTable
set AffiliationsSameForAllDOI = 1
where DOI in (
    select DOI
    from TempSourceTable
    where DOI in (
        select DOI
        from TempSourceTable
        group by DOI
        having count(distinct AffiliationsChecksum) = 1
    )
    group by DOI
    having count(distinct Affiliations) = 1
)

我希望它能比其他產品更好,因為它應該在對索引的一次掃描中執行。 同樣,最小/最大“技巧”避免了必須收集和維護每個不同的值。

WITH X AS 
(
  SELECT *,
    AffiliationsSameForAllDOI_New =
      CASE WHEN MAX(Affiliations) OVER (PARTITION BY DOI)
        = MIN(Affiliations) OVER (PARTITION BY DOI)
      THEN 1
      ELSE 0
      END
  FROM TempSourceTable 
)
UPDATE X
SET AffiliationsSameForAllDOI = AffiliationsSameForAllDOI_New
WHERE AffiliationsSameForAllDOI_New = 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM