2012-07-14 90 views
1

我有一張需要執行查詢的約3000萬條記錄。從我的閱讀中,我認爲使用最左前綴與我需要選擇的所有字段的組合索引是正確的方法,但是當我在查詢上運行解釋時,甚至不使用索引。使用索引優化此查詢的最佳方式是什麼?

這是查詢:

select distinct email FROM my_table 
WHERE `customer_id` IN(278,428,186,40,208,247,59,79,376,73,38,52,68,227) 
AND `company_id` = 4 
AND `active` = 1 
AND `date` > '2012-04-15'; 

的解釋看起來像這樣

+----+-------------+--------+-------+---------------+-------+---------+------+----------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows  | Extra  | 
+----+-------------+--------+-------+---------------+-------+---------+------+----------+-------------+ 
| 1 | SIMPLE  | emails | index | customer_id | email | 772  | NULL | 29296705 | Using where | 
+----+-------------+--------+-------+---------------+-------+---------+------+----------+-------------+ 

這些領域

`id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
`email` varchar(255) NOT NULL DEFAULT '', 
`customer_id` int(10) unsigned DEFAULT NULL, 
`company_id` int(10) unsigned NOT NULL, 
`active` tinyint(1) unsigned NOT NULL DEFAULT '1',                                    
`date` date DEFAULT NULL 

指標看起來像這樣

PRIMARY KEY (`id`),                                                       
UNIQUE KEY `email` (`email`,`customer_id`),                                                 
KEY `customer_id` (`customer_id`,`company_id`,`active`,`date`) 

我不太確定優化這個的最佳方法是什麼。

+2

它看起來優化了我.. – Samson 2012-07-14 20:01:01

+0

@radashk該查詢只返回3,117,636行。在解釋中,它表明它有將近3000萬行需要過濾。 – Zach 2012-07-14 20:13:19

+1

這些都是您使用WHERE IN子句的所有情況。它不能索引。 – Samson 2012-07-14 20:15:14

回答

1

MySQL在索引左側經常大約是IN。嘗試查詢每個customer_id並查看是否使用您的索引。您可以使用UNION語法將它們連接在一起。另一種可能性是,MySQL認爲對於10%的行來篩選所有內容比對其嘗試使用索引更快。

+0

它確實使用索引時,我這樣做。我注意到,如果我做了一個強制索引(customer_id),解釋只會顯示630萬,這是一個巨大的進步。 – Zach 2012-07-14 23:23:24

+0

我會花兩次查詢,每次運行幾次。 MySQL認爲不使用索引會更快,而且它可能是正確的。 – 2012-07-15 16:40:44

+0

每次都查詢5次,使用FORCE INDEX絕對是一個改進。原始查詢的時間分別爲26.4,25.4,27.7,25.1和25.5。 FORCE INDEX查詢的時間是14.1,14.3,14.3,13.9和14.9。 – Zach 2012-07-15 22:40:29

相關問題