Performance

使用非等值連接提高映射標準化值的性能 - LIKE 運算符

  • December 31, 2019

我有一個大型數據倉庫臨時表(約 250 萬行),它使用映射表來標準化文本列。我有一個執行良好的更新語句,但性能很差,並且想要一些關於修改語句和/或標準化數據的替代策略的建議。

源文本可以包含任何內容,我基本上是在字元串中尋找關鍵字。由於數據的性質,較長的字元串更具體,因此更正確,因此我想獲得為暫存表中每個給定行找到的最長映射值。

源數據(簡化):

CREATE TABLE STAGINGTABLE (TextColumn VARCHAR(100));

INSERT INTO STAGINGTABLE VALUES ('This entry has a full foo bar entry');
INSERT INTO STAGINGTABLE VALUES ('Today was a foo day');
INSERT INTO STAGINGTABLE VALUES ('Only found bar data');
INSERT INTO STAGINGTABLE VALUES ('Blah blah blah');

CREATE TABLE MAPPING (SourceMap VARCHAR(100), TargetMap VARCHAR(100));

INSERT INTO MAPPING VALUES ('%FOO BAR%', 'Foo Bar');
INSERT INTO MAPPING VALUES ('%FOO%', 'Foo');
INSERT INTO MAPPING VALUES ('%BAR%', 'Bar');
INSERT INTO MAPPING VALUES ('%%', 'Unknown');

更新聲明:

UPDATE STAGINGTABLE
SET TextColumn = (
   SELECT TargetMap
   FROM (
       SELECT TargetMap
       , ROW_NUMBER() OVER (PARTITION BY TextColumn
           ORDER BY LEN(SourceMap) DESC) AS ROWNUM
       FROM STAGINGTABLE
       INNER JOIN MAPPING
           ON UPPER(TextColumn) LIKE SourceMap
       WHERE TextColumn IS NOT NULL
   ) AS STG_MAP
   WHERE ROWNUM = 1
);

映射後臨時表中的最終值:

Foo Bar
Foo
Bar
Unknown

編輯: TextColumn 和 SourceMap 列確實具有非聚集索引。

感謝大家的意見和建議,我嘗試了@mustaccio發布的所有想法,但最終最快的策略是完全放棄映射表,只用一個大醜CASE語句來處理所有情況,並插入到另一個臨時表中。執行時間下降到只有幾秒鐘,我無法反駁。要處理的情況大多是靜態的,所以如果我必須每年重新部署一次或兩次 SSIS 包以在出現新情況時添加新情況,那就這樣吧。

最後的範例插入語句(不准確,只是記憶體不足):

INSERT INTO STAGINGTABLE_TWO (TextColumn) 
SELECT 
 CASE
   WHEN TextColumn LIKE '%FOO BAR%' THEN 'Foo Bar'
   WHEN TextColumn LIKE '%FOO%' THEN 'Foo'
   WHEN TextColumn LIKE '%BAR%' THEN 'Bar'
   ELSE 'Unknown'
 END
FROM STAGINGTABLE;

引用自:https://dba.stackexchange.com/questions/255881