2016-01-23 49 views
2

我有一个超过3500万行的大型索引表。这里有指标,有一个命名约定,显示他们的顺序列顺序:为什么MySQL选择该索引,以及速度太慢?

IDX_E93438363DAE128B, 
IDX_LIST_ID_EMAIL_ADDRESS_DELETED, 
IDX_LIST_ID_SUBSCRIBED_DELETED_EMAIL_ADDRESS, 
IDX_LIST_ID_SUBSCRIBED_DELETED_FIRST_NAME, 
IDX_LIST_ID_SUBSCRIBED_DELETED_LAST_UPDATED_AT 

我在我的媒体亚马逊RDS实例此表的查询向上走15分钟:

SELECT * FROM contact 
WHERE list_id = '014c7cba-c124-11e5-b4ea-0a4287b2e8c5' 
AND subscribed = 1 
AND deleted = 0 

使用的EXPLAIN查询我可以看到MySQL选择使用IDX_LIST_ID_EMAIL_ADDRESS_DELETED密钥,当我期望大多数其他密钥(IDX_LIST_ID_SUBSCRIBED_DELETED_...)更加优化。

我应该相信引擎吗? 17分钟左右的时间是一个现实的时间来等待一个表上的查询这么大?

+0

你需要使用'SELECT *'吗?通过这样做,您可以强制数据库返回到其索引所找到的每一行的主键行。另外,什么引擎? MyISAM或InnoDB? –

+0

感谢您的回复。我已经将我的查询提炼为“SELECT id,email_address,first_name,last_name FROM ...',但我仍然遇到同样的问题。我正在使用InnoDB。 – Jonathan

+0

当您从联系人使用索引(idx_list_id_subscribed_deleted_first_name)中选择*时,性能会怎样?'? – zedfoxus

回答

0
SELECT id, email_address, first_name, last_name 
FROM contact 
WHERE list_id = '014c7cba-c124-11e5-b4ea-0a4287b2e8c5' 
AND subscribed = 1 
AND deleted = 0 

鉴于上面的查询,最好的指数将

ALTER TABLE `contact` 
CREATE INDEX (`list_id`,`subscribed`,`deleted`,`email_address`,`first_name`,`last_name`) 

,将允许它来查找最左边的3个字段所有必要的行,所有剩余价值的存在是为了权那。这假定id是你的表的主键,否则你将不得不在该索引的deleted的右边添加它。

这应该最大限度地提高可以运行此查询的速度,至少就像改变索引一样。

如果这个指标,你仍然有问题,请让我们知道的

SELECT COUNT(*) 
FROM contact 
WHERE list_id = '014c7cba-c124-11e5-b4ea-0a4287b2e8c5' 
AND subscribed = 1 
AND deleted = 0 

返回结果。你可能只有很多行,这可能需要一段时间才能返回。