2012-06-29 66 views
0

我原來問這個問題here優化MySQL查詢以查找重複項?

我正在使用以下查詢返回具有相同名字和姓氏的所有重複記錄。訣竅是contact_id必須按降序排列。

問題是數據庫在「contacts」表中有幾百萬條記錄。他們需要幾分鐘才能完成。

我有contact_firstName,contact_lastName,contact_client_id和contact_id在數據庫中索引所有。

有關如何進一步優化此查詢的其他想法?

SELECT c.contact_id, c.contact_purl, c.contact_firstName, c.contact_lastName, c.contact_organization 
FROM (
     SELECT contact_purl, contact_firstName, contact_lastName, MIN(contact_id) AS MinID 
     FROM contacts 
     WHERE contact_client_id = 1 
     GROUP BY contact_purl HAVING COUNT(contact_id) > 1) t 
INNER JOIN contacts c 
ON t.contact_purl = c.contact_purl 
AND c.contact_client_id = 1 
AND t.MinID <> c.contact_id 
ORDER BY contact_id asc 

說明: enter image description here

架構:

CREATE TABLE IF NOT EXISTS `contacts` (
    `contact_id` int(11) NOT NULL AUTO_INCREMENT, 
    `contact_client_id` int(11) DEFAULT NULL, 
    `contact_sales_id` int(11) DEFAULT NULL, 
    `contact_campaign_id` int(11) DEFAULT NULL, 
    `contact_purl` varchar(100) NOT NULL, 
    `contact_purl1` varchar(50) DEFAULT NULL, 
    `contact_purl2` varchar(50) DEFAULT NULL, 
    `contact_firstName` varchar(50) NOT NULL, 
    `contact_lastName` varchar(50) NOT NULL, 
    `contact_organization` varchar(100) DEFAULT NULL, 
    `contact_url_organization` varchar(200) DEFAULT NULL, 
    `contact_position` varchar(50) DEFAULT NULL, 
    `contact_email` varchar(100) DEFAULT NULL, 
    `contact_phone` varchar(20) DEFAULT NULL, 
    `contact_fax` varchar(20) NOT NULL, 
    `contact_address1` varchar(100) DEFAULT NULL, 
    `contact_address2` varchar(100) DEFAULT NULL, 
    `contact_city` varchar(100) DEFAULT NULL, 
    `contact_state` varchar(20) DEFAULT NULL, 
    `contact_zip` varchar(10) DEFAULT NULL, 
    `contact_IP` varchar(50) DEFAULT NULL, 
    `contact_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    `contact_pw` varchar(200) NOT NULL, 
    `contact_subscribed` varchar(1) NOT NULL DEFAULT 'Y', 
    `contact_import` varchar(200) DEFAULT NULL, 
    `contacts_c_1` varchar(500) DEFAULT NULL, 
    `contacts_c_2` varchar(500) DEFAULT NULL, 
    `contacts_c_3` varchar(500) DEFAULT NULL, 
    `contacts_c_4` varchar(500) DEFAULT NULL, 
    `contacts_c_5` varchar(500) DEFAULT NULL, 
    `contacts_c_6` varchar(500) DEFAULT NULL, 
    `contacts_c_7` varchar(500) DEFAULT NULL, 
    `contacts_c_8` varchar(500) DEFAULT NULL, 
    `contacts_c_9` varchar(500) DEFAULT NULL, 
    `contacts_c_10` varchar(500) DEFAULT NULL, 
    `contacts_c_11` varchar(500) DEFAULT NULL, 
    `contacts_c_12` varchar(500) DEFAULT NULL, 
    `contacts_c_13` varchar(500) DEFAULT NULL, 
    `contacts_c_14` varchar(500) DEFAULT NULL, 
    `contacts_c_15` varchar(500) DEFAULT NULL, 
    `contacts_c_16` varchar(500) DEFAULT NULL, 
    `contacts_c_17` varchar(500) DEFAULT NULL, 
    `contacts_c_18` varchar(500) DEFAULT NULL, 
    `contacts_c_19` varchar(500) DEFAULT NULL, 
    `contacts_c_20` varchar(500) DEFAULT NULL, 
    `contacts_c_21` varchar(500) DEFAULT NULL, 
    `contacts_c_22` varchar(500) DEFAULT NULL, 
    `contacts_c_23` varchar(500) DEFAULT NULL, 
    `contacts_c_24` varchar(500) DEFAULT NULL, 
    `contacts_c_25` varchar(500) DEFAULT NULL, 
    `contacts_c_26` varchar(500) DEFAULT NULL, 
    `contacts_c_27` varchar(500) DEFAULT NULL, 
    `contacts_c_28` varchar(500) DEFAULT NULL, 
    `contacts_c_29` varchar(500) DEFAULT NULL, 
    `contacts_c_30` varchar(500) DEFAULT NULL, 
    `contacts_c_31` varchar(500) DEFAULT NULL, 
    `contacts_c_32` varchar(500) DEFAULT NULL, 
    `contacts_c_33` varchar(500) DEFAULT NULL, 
    `contacts_c_34` varchar(500) DEFAULT NULL, 
    `contacts_c_35` varchar(500) DEFAULT NULL, 
    `contacts_c_36` varchar(500) DEFAULT NULL, 
    `contacts_c_37` varchar(500) DEFAULT NULL, 
    `contacts_c_38` varchar(500) DEFAULT NULL, 
    `contacts_c_39` varchar(500) DEFAULT NULL, 
    `contacts_c_40` varchar(500) DEFAULT NULL, 
    `contacts_c_41` varchar(500) DEFAULT NULL, 
    `contacts_c_42` varchar(500) DEFAULT NULL, 
    `contacts_c_43` varchar(500) DEFAULT NULL, 
    `contacts_c_44` varchar(500) DEFAULT NULL, 
    `contacts_c_45` varchar(500) DEFAULT NULL, 
    `contacts_c_46` varchar(500) DEFAULT NULL, 
    `contacts_c_47` varchar(500) DEFAULT NULL, 
    `contacts_c_48` varchar(500) DEFAULT NULL, 
    `contacts_c_49` varchar(500) DEFAULT NULL, 
    `contacts_c_50` varchar(500) DEFAULT NULL, 
    `contacts_i_1` varchar(100) DEFAULT NULL, 
    `contacts_i_2` varchar(100) DEFAULT NULL, 
    `contacts_i_3` varchar(100) DEFAULT NULL, 
    `contacts_i_4` varchar(100) DEFAULT NULL, 
    `contacts_i_5` varchar(100) DEFAULT NULL, 
    `contacts_i_6` varchar(100) DEFAULT NULL, 
    `contacts_i_7` varchar(100) DEFAULT NULL, 
    `contacts_i_8` varchar(100) DEFAULT NULL, 
    `contacts_i_9` varchar(100) DEFAULT NULL, 
    `contacts_i_10` varchar(100) DEFAULT NULL, 
    `contacts_i_11` varchar(100) DEFAULT NULL, 
    `contacts_i_12` varchar(100) DEFAULT NULL, 
    `contacts_i_13` varchar(100) DEFAULT NULL, 
    `contacts_i_14` varchar(100) DEFAULT NULL, 
    `contacts_i_15` varchar(100) DEFAULT NULL, 
    PRIMARY KEY (`contact_id`), 
    KEY `contact_campaign_id` (`contact_campaign_id`), 
    KEY `contact_client_id` (`contact_client_id`), 
    KEY `contact_purl2` (`contact_purl2`), 
    KEY `contact_purl1` (`contact_purl1`), 
    KEY `contact_purl` (`contact_purl`) 
) 
+2

查詢計劃和架構,請。 – 2012-06-29 18:46:28

+2

快速提示:在MySQL中,'GROUP BY'自動應用'ORDER BY',因爲......沒有人知道。爲了防止這種行爲加快你的查詢速度,在分組查詢中加入'ORDER BY NULL'。 – biziclop

+0

謝謝,整潔的祕密 – Sebas

回答

1

你可以這樣做只是讓自身的聯接,這樣的:

SELECT DISTINCT c1.contact_id, c1.contact_firstName, c1.contact_lastName, 
     RIGHT(c1.contact_lastName,1) AS nameNum 
FROM 
     contacts c1 INNER JOIN contacts c2 
     ON c1.contact_firstName = c2.contact_firstName 
     AND c1.contact_lastName = c2.contact_lastName 
     AND c2.contact_client_id = 1 
     AND c1.contact_id <> c2.contact_id 
ORDER BY c1.contact_id DESC 
+0

感謝Spaeth,但是這花了更長的時間來執行。在幾分鐘的範圍內! –

0

會是有意義的分別跟蹤每個客戶端的聯繫人數量並將其存儲在ano中有沒有列vs每次做這個子選擇查詢?

使用這些記錄數,可能會更有效地存儲其中一些計算結果,而不必實時查詢它們。