簡單的索引選擇查詢需要 350 秒 (?!) 即使過濾 100.00“使用索引條件”
我的日誌顯示,此處解釋的查詢花費了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
我認為需要 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
此查詢的最佳索引將是具有 4 列的複合索引,順序不限:
INDEX(contact_id, job_class_name, execute_at, deleted_at)
而且,根據您選擇的順序,您可以擺脫現有的 KEY 之一。
注意反斜杠。
'App\Jobs\MyJob'
可被視為App[LF]obs[CR]yJob
或AppJobsMyJob
。352秒實在是太不合理了。也許其他事情正在發生,並阻止對行和/或表的訪問?(352s 是假的。)
“使用索引條件”與“使用索引”不同。後者表示一個“覆蓋索引”,對於這個查詢和表來說是不實用的。