【发布时间】:2021-12-21 22:54:51
【问题描述】:
我有以下表格:
CREATE TABLE `sms` (
`sms_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sms_datetime` datetime DEFAULT NULL,
`sms_number` varchar(40) NOT NULL,
`sms_text` text,
`sms_status` int(3) DEFAULT '0',
`sms_last_tm` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`sms_csinteve_id` int(11) unsigned NOT NULL DEFAULT '0',
`sms_handler_user_id` int(11) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`sms_id`),
KEY `sms_number` (`sms_number`),
KEY `sms_last_tm` (`sms_last_tm`),
KEY `sms_csinteve_id` (`sms_csinteve_id`),
KEY `sms_handler_user_id` (`sms_handler_user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
sms 的行数比 2,000,000 多。
还有下表:
CREATE TABLE `customer_service_interaction_events` (
`csinteve_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`csinteve_interaction_id` int(11) unsigned NOT NULL DEFAULT '0',
`csinteve_datetime` datetime DEFAULT NULL,
PRIMARY KEY (`csinteve_id`),
KEY `csinteve_interaction_id` (`csinteve_interaction_id`),
KEY `csinteve_datetime` (`csinteve_datetime`)
) ENGINE=InnoDB AUTO_INCREMENT=21153 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
20,000 行。
然后这个查询:
EXPLAIN SELECT COUNT(csinteve_id) as interactions_number
FROM customer_service_interaction_events
JOIN sms
ON csinteve_id = sms_csinteve_id
WHERE csinteve_interaction_id = 3085
AND sms_handler_user_id = 0;
说:
{
"data":
[
{
"id": 1,
"select_type": "SIMPLE",
"table": "customer_service_interaction_events",
"partitions": null,
"type": "ref",
"possible_keys": "PRIMARY,csinteve_interaction_id",
"key": "csinteve_interaction_id",
"key_len": "4",
"ref": "const",
"rows": 1,
"filtered": 100,
"Extra": "Using index"
},
{
"id": 1,
"select_type": "SIMPLE",
"table": "sms",
"partitions": null,
"type": "ALL",
"possible_keys": "sms_csinteve_id,sms_handler_user_id",
"key": null,
"key_len": null,
"ref": null,
"rows": 2083577,
"filtered": 99.4,
"Extra": "Using where; Using join buffer (Block Nested Loop)"
}
]
}
说对于sms 表MySQL 不使用任何索引(类型ALL)。
而sms 表在与customer_service_interaction_events 连接的sms_csinteve_id 列上有一个索引,而customer_service_interaction_events 表在csinteve_interaction_id 上有一个索引。
查询的目的是返回未处理的短信数量(sms),每条短信绑定一个客服事件(customer_service_interaction_events),多个客服事件有相同的交互id(customer_service_interaction_events.csinteve_interaction_id) , 在示例中为 3085)。
谢谢。
编辑:
我尝试添加 Akina 的索引:
CREATE INDEX idx ON customer_service_interaction_events (csinteve_interaction_id, csinteve_id);
CREATE INDEX idx ON sms (sms_handler_user_id, sms_csinteve_id);
但是解释:
EXPLAIN SELECT COUNT(csinteve_id) as interactions_number
FROM customer_service_interaction_events
JOIN sms
ON csinteve_id = sms_csinteve_id
WHERE csinteve_interaction_id = 3085
AND sms_handler_user_id = 0;
仍然为sms 输出类型ALL:
{
"data":
[
{
"id": 1,
"select_type": "SIMPLE",
"table": "customer_service_interaction_events",
"partitions": null,
"type": "ref",
"possible_keys": "PRIMARY,csinteve_interaction_id,csinteve_interaction_id__csinteve_id",
"key": "csinteve_interaction_id",
"key_len": "4",
"ref": "const",
"rows": 1,
"filtered": 100,
"Extra": "Using index"
},
{
"id": 1,
"select_type": "SIMPLE",
"table": "sms",
"partitions": null,
"type": "ref",
"possible_keys": "sms_csinteve_id,sms_handler_user_id,sms_csinteve_id_2,sms_handler_user_id_2,sms_csinteve_id_3,sms_handler_user_id_3,sms_csinteve_id_4,sms_handler_user_id_4,sms_handler_user_id__sms_csinteve_id",
"key": "sms_handler_user_id__sms_csinteve_id",
"key_len": "8",
"ref": "const,local_bluelinks.customer_service_interaction_events.csinteve_id",
"rows": 2083577,
"filtered": 100,
"Extra": "Using index"
}
]
}
【问题讨论】:
标签: mysql sql database-indexes secondary-indexes