簡體   English   中英

MySql:將同一張表加入數百萬行

[英]MySql: joining same table with millions rows

我有一個包含數百萬行的表(SF_COLLECTIONS)

ID MEMBERID COLLECTIONID CARDID STATE (D / M)
1  1        1            1      D
2  1        1            2      D
3  2        1            1      M
4  2        1            2      M
5  2        1            3      D
6  1        1            3      M

我必須將那些 MEMBERID = 1 和 STATE = D 與那些 MEMBERID = 2 和 STATE = M 交叉,反之亦然

這是我的查詢

SELECT 1
    FROM sf_collections AS rac
    INNER JOIN sf_collections AS myrac 
        ON 
        (myrac.cardid = rac.cardid AND 
            (
                (myrac.state = "M" AND rac.state = "D") OR 
                (myrac.state = "D" AND rac.state = "M")
            )
        ) 
    WHERE
    rac.memberid = 1 AND myrac.memberid = 2
    GROUP BY rac.memberid

(響應時間約 4 秒)

這是一種有效的方法還是有更好的方法來提高性能?

樣本數據集:

CREATE TABLE `sf_collections` (
 `id` int(11) NOT NULL auto_increment,
 `memberid` int(11) NOT NULL,
 `collectionid` int(11) NOT NULL,
 `cardid` int(11) NOT NULL,
 `state` varchar(1) NOT NULL,
 PRIMARY KEY  (`id`),
 UNIQUE KEY `sf_collections_pkey` (`memberid`,`collectionid`,`cardid`,`state`),
 KEY `collectionid` (`collectionid`),
 KEY `memberid` (`memberid`),
 KEY `cardid` (`cardid`),
 KEY `state` (`state`)
) ENGINE=MyISAM AUTO_INCREMENT=22627806 DEFAULT CHARSET=latin1

INSERT INTO sf_collections (memberid,collectionid,cardid,state) VALUES
(1,1,1,'D'),
(1,1,2,'D'),
(1,1,3,'M'),
(2,1,1,'M'),
(2,1,2,'M'),
(2,1,3,'D');

SELECT 1
    FROM sf_collections AS rac
    INNER JOIN sf_collections AS myrac 
        ON 
        (myrac.cardid = rac.cardid AND 
            (
                (myrac.state = "M" AND rac.state = "D") OR 
                (myrac.state = "D" AND rac.state = "M")
            )
        ) 
    WHERE
    rac.memberid = 1 AND myrac.memberid = 2
    GROUP BY rac.memberid

和 db-fiddle

謝謝

編輯:MySql 是 5.0(很舊,無法升級)

INDEX(cardid)替換為 INDEX INDEX(cardid, state)

如果可行,不要同時檢查 D->M 和 M->D; 只做一個方向。 這將減少一半的努力。

避免SELECT... GROUP BY...通過切換到EXISTS ( SELECT 1... ) 如果有多個匹配的行,這將加快速度。 如果您最終要“列出匹配項”,我們不妨看看您想要什么,而不是挑剔GROUP BY的不當使用。 你會使用GROUP_CONCAT嗎?

從 MyISAM 遷移到 InnoDB。 即使在 5.0 中,這個查詢本質上也可能更快。

DROP INDEX(memberid)因為唯一索引處理此類。

你有什么需要id嗎? 如果不是,請擺脫它並將 4 列UNIQUE索引提升為PRIMARY KEY

如果state只是一個標志 (0/1),則可能永遠不會使用INDEX(state) 算了吧。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM