2011-05-15 28 views
1

我有一個程序,它具有顯示AT至少2重複在MySQL記錄中類似的字符串的功能,我有一個當前的實現工作得很好,但對於300K記錄太慢。如何在MySQL中查詢重複的字符串條目

接觸。例如表條目:

 
id (int)| name (string) | phone (string) 
----------------------------------------- 
1  | mike   | 081239812345678 
2  | jhon   | 082222212345678 
3  | rudy   | 081237712345678 
4  | lucy   | 081237712345123 
5  | lily   | 081244412345678 

我需要記錄屬於「邁克,JHON,魯迪和百合」,因爲他們最後的電話號碼中的數字8是相同的(複製),但創紀錄的歸屬露西被忽略(因爲沒有其他記錄也有類似的8位結束號碼)

我目前的方法是使用2個查詢:

我的第一個查詢:

 
"select right(phoner, 8) as myRight 
    , count(*) as totdup 
    from contact 
    group by myRight 
    having totdup > 1"; 

從該查詢,我可以得到的「myRight」的值,然後我執行第二查詢,以獲得細節:

 
"select * from contact where phone like '%$myRight'"; 

我的問題是如何,因爲我有300K的記錄,它需要加快進程這個查詢大約需要20分鐘,我還希望通過只使用1個查詢簡化查詢,但我不知道如何,我已經爲這個問題奮鬥了幾天,現在您的幫助將非常感激。

回答

0

它看起來像是在第一個查詢的結果行上運行一個循環,併爲每個這樣的行執行第二個查詢一次。

我建議把第一個結果到一個臨時表,然後做

SELECT contact.* FROM contact JOIN temporary 
WHERE right(contact.phoner, 8) = temporary.myRight 

把臨時表上的索引更可能會提高你的表現。

0

根據您正在使用的MySQL版本,這可能工作:

select * 
from contact 
where RIGHT(phone, 8) IN (
select right(phone, 8) as myRight 
    from contact 
    group by myRight 
    having COUNT(*) > 1 
) 
1

如果您存儲在相反的順序PHONENUMBERS的(8)最右邊的字符,然後
您的表將具有以下田:

id (int)| name (string) | phone (string) | phonerev (string) 
---------------------------------------------------- 
1  | mike   | 081239812345678 | 876543218932180 
2  | jhon   | 082222212345678 | 876543212222280 
3  | rudy   | 081237712345678 | 876543217732180 
4  | lucy   | 081237712345123 | 321543217732180 
5  | lily   | 081244412345678 | 876543214442180 

,你可以做一個查詢,如:

select right(phone,8) as myRight 
from contact c1 
inner join contract c2 on (left(c1.phonerev,8) = left(c2.phonerev,8) 
          and c1.id <> c2.id) 
group by left(phonerev,8) 

這樣做確保您在phonerev

設置索引可以統一查詢:

select c1.* 
from contact c1 
inner join contract c2 on (left(c1.phonerev,8) = left(c2.phonerev,8) 
          and c1.id <> c2.id) 

這將允許在PHONENUMBER

使用索引的。如果你只是存放8然後查詢變爲:

select right(phone,8) as myRight 
from contact c1 
inner join contract c2 on (c1.phonerev,8 = c2.phonerev 
          and c1.id <> c2.id) 
group by phonerev; 

哪個更快。

0

@Johan,你給了我一個加速查詢的好方向,我爲最右邊的8個字符的手機添加了一個新字段,避免在查詢中使用「right(phone,8)」。

@願意A,感謝您的幫助,但查詢實際上比我當前的解決方案慢,我不知道爲什麼。

@LMMathies,你的想法很好,但是用臨時表來存儲myRight不適用於我的服務器/數據庫條件。

謝謝各位〜