我試圖優化一個查詢,花費太長時間才能運行它。它似乎陷入了很多發送數據中,需要大約半個小時才能運行。優化大型MySQL查詢
$campaignIDs = "31,36,37,40,41,42,43,50,51,62,64,65,66,67,68,69,84,338,339,355,431,505,530,549,563,694,752,754,755,760,769,772,777,798,799,800,806,816,821,855,856,945,989,1007,1030,1032,1047,1052,1054,1066,1182,1268,1281,1298,1301,1317,1348,1447,1461,1471,1589,1602,1604,1615,1622,1650,1652,1709"; SELECT Email, Type, CampaignID FROM Refer WHERE (Type = 'V' OR Type = 'C') AND (EmailDomain = 'yahoo.com') AND (ListID = 1) AND CampaignID IN ($campaignIDs) AND Date >= DATE_SUB(NOW(), INTERVAL 90 DAY)
下面介紹一下參考表如下所示:
+-------------+------------------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+------------------+------+-----+-------------------+----------------+ | ID | int(10) unsigned | NO | PRI | NULL | auto_increment | | CampaignID | int(10) unsigned | NO | MUL | NULL | | | Type | char(1) | NO | MUL | NULL | | | Date | timestamp | NO | | CURRENT_TIMESTAMP | | | IP | varchar(16) | NO | | NULL | | | Useragent | varchar(200) | YES | | NULL | | | Referrer | varchar(200) | YES | | NULL | | | Email | varchar(200) | NO | MUL | NULL | | | EmailDomain | varchar(200) | YES | MUL | NULL | | | FolderName | varchar(200) | NO | | NULL | | | ListID | int(10) unsigned | NO | MUL | 1 | | +-------------+------------------+------+-----+-------------------+----------------+
這裏有指標:
+-------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | +-------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | refer | 0 | PRIMARY | 1 | ID | A | 148581841 | NULL | NULL | | BTREE | | | refer | 1 | id_email | 1 | Email | A | 18572730 | NULL | NULL | | BTREE | | | refer | 1 | id_type | 1 | Type | A | 19 | NULL | NULL | | BTREE | | | refer | 1 | id_emaildomain | 1 | EmailDomain | A | 19 | NULL | NULL | YES | BTREE | | | refer | 1 | id_campaignid | 1 | CampaignID | A | 19 | NULL | NULL | | BTREE | | | refer | 1 | id_listid | 1 | ListID | A | 19 | NULL | NULL | | BTREE | | | refer | 1 | id_emailtype | 1 | Email | A | 24763640 | NULL | NULL | | BTREE | | | refer | 1 | id_emailtype | 2 | Type | A | 37145460 | NULL | NULL | | BTREE | | | refer | 1 | idx_cidtype | 1 | CampaignID | A | 19 | NULL | NULL | | BTREE | | | refer | 1 | idx_cidtype | 2 | Type | A | 19 | NULL | NULL | | BTREE | | +-------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
這裏的輸出EXPLAIN SELECT:
+----+-------------+-------+-------+------------------------------------------------------------+---------------+---------+------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+------------------------------------------------------------+---------------+---------+------+---------+-------------+ | 1 | SIMPLE | Refer | range | id_type,id_emaildomain,id_campaignid,id_listid,idx_cidtype | id_campaignid | 4 | NULL | 3605121 | Using where | +----+-------------+-------+-------+------------------------------------------------------------+---------------+---------+------+---------+-------------+
有表中約有150M行。
有什麼我可以做的,以優化有問題的查詢?我是否需要添加索引或其他內容?我怎樣才能讓事情變得更好?