我正在尋找從我的數據庫中刪除重複記錄的有效方法。首先,我使用了一個使用連接等的存儲過程,這導致查詢執行非常緩慢。現在,我正在嘗試一種不同的方法。請考慮以下查詢:從數百萬條記錄中刪除重複行的有效方法
/* QUERY A */
SELECT *
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value
此查詢僅在12秒內執行,結果爲182.400條記錄。表中的行數目前爲420.930.407,col1和col3爲索引。
下一個查詢:
/* QUERY B */
WITH ALL_RECORDS AS
(SELECT id
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value)
SELECT *
FROM ALL_RECORDS
這個查詢用了不到2秒,並給我的182.400記錄在表中的所有ID的(根據where子句)。
然後,我的最後一次查詢,是選擇對我想組的列分組中的所有記錄最低(第一)的識別碼,以檢查重複的查詢:再次
/* QUERY C */
SELECT MIN(id)
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value
GROUP BY col1,
col2,
col3,
col4,
col5,
col6
,這個查詢執行在不到2秒內。結果是30.400,這意味着在獨特的182.400條記錄中有30.400條獨特記錄。
現在,我想刪除(或者,首先選擇以確保我有我的查詢權限)所有不是唯一的記錄。所以,我想從my_table中刪除182.400 - 30.400 = 152.000條記錄。
我想我會結合最後兩個查詢:根據col1,col2和col3(查詢B)的where子句獲取屬於我的數據集的所有id,然後從該數據集中刪除/選擇所有記錄該ID不在唯一記錄標識的ID列表中(查詢C)。
但是,當我從查詢B中選擇所有查詢B.id NOT IN查詢C時,查詢不需要2,4或12(14或16)秒,但似乎需要永遠(在後顯示20.000條記錄1分鐘,2分鐘後約爲40.000,所以我取消了查詢,因爲它會找到152.000條記錄,這將花費8分鐘)。
WITH ALL_RECORDS AS
(SELECT id
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value)
SELECT id
FROM ALL_RECORDS
WHERE id NOT IN
(SELECT MIN(id)
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value
GROUP BY col1,
col2,
col3,
col4,
col5,
col6)
我知道NOT IN
是緩慢的,但我不能掌握它是如何的這種緩慢的(因爲沒有不參與各不超過2秒執行這兩個查詢)。
有沒有人對我如何解決這個難題有一些很好的建議?
------------------更多信息------------------
以前的解決方案是遵循存儲過程。出於某種原因,它在我的接受環境中完美執行,但不在我的生產環境中執行。目前,我們有超過4億的產量記錄和超過200萬條記錄被接受,所以這可能是一個原因。
DELETE my_table
FROM my_table
LEFT OUTER JOIN
(SELECT MIN(id) AS RowId,
col1,
col2,
col3,
col4,
col5,
col6
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value
GROUP BY col1,
col2,
col3,
col4,
col5,
col6) AS KeepRows ON my_table.id = KeepRows.RowId
WHERE KeepRows.RowId IS NULL
AND my_table.col1 = value
AND my_table.col2 = value
AND my_table.col3 = value
我已經基於計算器另一個答案該解決方案(不能在此刻找到它),但我覺得我應該能夠創建基於查詢B和C內的幾個執行查詢秒...
這似乎工作得非常快,謝謝!我會盡力實施它明天,並希望它會運行在生產以及:) – Tjab