尽管在使用
join
和 order by
时都有索引,但我在 MySQL 方面遇到了性能问题。该查询当前需要 77 秒 才能完成。
查询的目的是按字母顺序对表进行排序。
我有一个 MySQL 数据库,其中包含两个 InnoDB 表。
report_urls
;和urls
每个表包含 500,000 条记录。
report_urls
和 url
之间存在一对一的关系。而 url
和 report_urls
之间存在一对多关系。
表格具有以下结构:
report_urls
id
(主键、char36、UUID、索引)
url_id
(char36、UUID、索引)
urls
id
(主键、char36、UUID、索引)
title
(varchar 255,已索引)
我需要连接这些表,并按
title
列的字母顺序对连接结果进行排序。
我正在使用 Laravel 和 Eloquent ORM,但生成的 SQL 语句是:
select
*
from
`report_urls`
inner join `urls` as `urls_title_sort` on `report_urls`.`url_id` = `urls_title_sort`.`id`
where
`report_id` = '8f6598f0-34d0-48b0-be8b-41c1b8f61ffd'
order by
`urls_title_sort`.`title` asc
limit
11 offset 0
使用
EXPLAIN
命令运行上述查询会输出以下内容:
id | 选择类型 | 桌子 | 分区 | 类型 | 可能的键 | 键 | key_len | 参考 | 行 | 过滤 | 额外 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 简单 | 报告网址 | 空 | 参考 | report_urls_url_id_foreign、report_urls_report_id_created_at_index | report_urls_report_id_created_at_index | 144 | 常量 | 235931 | 100.00 | 临时使用;使用文件排序 |
1 | 简单 | url_标题_排序 | 空 | eq_ref | 小学 | 小学 | 144 | 数据库.report_urls.url_id | 1 | 100.00 | 空 |
SHOW CREATE TABLE report_urls;
的输出如下:
CREATE TABLE `report_urls` (
`id` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`report_id` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`url_id` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`violation_count` int unsigned NOT NULL DEFAULT '0',
`resolved_violation_count` int unsigned NOT NULL DEFAULT '0',
`violation_minor` int unsigned NOT NULL DEFAULT '0',
`violation_moderate` int unsigned NOT NULL DEFAULT '0',
`violation_serious` int unsigned NOT NULL DEFAULT '0',
`violation_critical` int unsigned NOT NULL DEFAULT '0',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `report_urls_url_id_foreign` (`url_id`),
KEY `report_urls_report_id_created_at_index` (`report_id`,`created_at`),
KEY `report_urls_report_id_index` (`report_id`),
KEY `report_urls_violation_count_index` (`violation_count`),
KEY `report_urls_resolved_violation_count_index` (`resolved_violation_count`),
KEY `report_urls_violation_minor_index` (`violation_minor`),
KEY `report_urls_violation_moderate_index` (`violation_moderate`),
KEY `report_urls_violation_serious_index` (`violation_serious`),
KEY `report_urls_violation_critical_index` (`violation_critical`),
KEY `report_urls_created_at_index` (`created_at`),
CONSTRAINT `report_urls_report_id_foreign` FOREIGN KEY (`report_id`) REFERENCES `reports` (`id`) ON DELETE CASCADE,
CONSTRAINT `report_urls_url_id_foreign` FOREIGN KEY (`url_id`) REFERENCES `urls` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
我需要将这些表格连接在一起并按标题字母顺序对它们进行排序。
该查询当前需要 77 秒 才能执行。我本来希望MySQL可以使用
title
索引,但是它似乎没有使用索引。
任何人都可以建议任何性能改进吗?