2008-11-26 56 views
5

我具有形式如何在MySQL中有效地查找重複的blob行?

CREATE TABLE data 
{ 
    pk INT PRIMARY KEY AUTO_INCREMENT, 
    dt BLOB 
}; 

它有大約16萬行和有關在BLOB列數據的2GB(平均每斑點14KB)的表。另一個表中有外鍵進入此表。

類似於3000的斑點是相同的。所以我想要的是一個查詢,它會給我一張重映射表,允許我刪除重複項。

簡易方法花了大約一個小時的30-40k行:

SELECT a.pk, MIN(b.pk) 
    FROM data AS a 
    JOIN data AS b 
    ON a.dt=b.dt 
    WHERE b.pk < a.pk 
    GROUP BY a.pk; 

我碰巧有,對於其他原因,有斑點的大小表:

CREATE TABLE sizes 
(
    fk INT, // note: non-unique 
    sz INT 
    // other cols 
); 

通過爲fk和另一個sz建立索引,直接查詢需要大約24秒和50k行:

SELECT da.pk,MIN(db.pk) 
    FROM data AS da 
    JOIN data AS db 
    JOIN sizes AS sa 
    JOIN sizes AS sb 
    ON 
     sa.size=sb.size 
    AND da.pk=sa.fk 
    AND db.pk=sb.fk 
    WHERE 
     sb.fk<sa.fk 
    AND da.dt=db.dt 
    GROUP BY da.pk; 

但是,這是對da(數據表)執行全表掃描。鑑於命中率應該相當低,我認爲索引掃描會更好。考慮到這一點,在第5次加入數據中添加了第3次數據副本,並且失去了大約3秒。

好的問題:我會比第二個選擇好得多嗎?如果是這樣,怎麼樣?

一個必然結論是:如果我有一個表格,其中鍵列的使用非常繁重,但其餘的應該只是很少使用,我會更好的添加該表格的另一個連接以鼓勵索引掃描與全表掃描?


XGC上#[email protected]指出,加入了效用表一樣大小,但與fk唯一約束可能有很大的幫助。一些有趣的觸發器和什麼不可能使它不壞以保持最新。

回答

10

您可以隨時對數據使用哈希函數(MD5SHA1),然後比較哈希值。

問題是如果你可以在你的數據庫中保存哈希值?

+0

+1:我同意這一點。如果每次查詢將陷入困境時必須爲字節比較做一個字節。確保添加記錄的代碼也將它們散列,併爲所有現有行生成散列。現在只需要比較blob大小和哈希值。 – 2008-11-26 07:32:14