我的日志显示,此处解释的查询花费了352.19 秒contact_id
(对于和不同的其他类似查询,时间也差不多execute_at
)。
EXPLAIN SELECT
*
FROM
`automations`
WHERE
(`contact_id` = 22638
AND `job_class_name` = 'App\Jobs\MyJob'
AND `execute_at` = '2018-12-15 16:43:00')
AND `automations`.`deleted_at` IS NULL
LIMIT 1
解释的结果:
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|----|-------------|-------------|------------|------|--------------------------------|--------------------------------|---------|-------------------------|------|----------|-----------------------|
| 1 | SIMPLE | automations | NULL | ref | cId_job_executeAt_delAt_unique | cId_job_executeAt_delAt_unique | 780 | const,const,const,const | 1 | 100.00 | Using index condition |
我在优化 MySql 方面没有经验,但我猜 Explain 看起来很棒,对吧?
为什么像这样的查询会花费 350 多秒?我该如何诊断和修复?
PS 这与我经常看到 的E_WARNING: Error while sending STMT_PREPARE packet. PID=*
错误有关。
CREATE TABLE `automations` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`contact_id` int(10) unsigned NOT NULL,
`job_class_name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`execute_at` datetime NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `cId_job_executeAt_delAt_unique` (`contact_id`,`job_class_name`,`execute_at`,`deleted_at`),
CONSTRAINT `automations_contact_id_foreign` FOREIGN KEY (`contact_id`) REFERENCES `contacts` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1519 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
此查询的最佳索引是一个包含 4 列的复合索引,顺序不限:
而且,根据您选择的顺序,您可以摆脱现有的 KEY 之一。
注意反斜杠。
'App\Jobs\MyJob'
可以被视为App[LF]obs[CR]yJob
或AppJobsMyJob
。352秒实在是不合理。也许发生了其他事情,阻止了对行和/或表的访问?(352s 是假的。)“使用索引条件”与“使用索引”不同。后者表示一个“覆盖索引”,这对于这个查询和表来说是不实用的。
我认为需要 352 秒的查询实际上只需要 0.352 秒!?♂️
https://laravel.io/forum/03-04-2014-what-time-format-does-dbgetquerylog-return告诉我 Laravel 的
DB::getQueryLog()
“时间”显示为毫秒(微秒乘以 1000),而不是秒。多么令人尴尬的错误(糟糕的假设)。所以我需要编辑我的 500 分赏金问题:https ://stackoverflow.com/questions/53469793/e-warning-error-while-sending-stmt-prepare-packet-pid/54374937?noredirect=1#comment95579631_53469793