我有一个 sync_log_lines
有数百万条记录的表。
CREATE TABLE `sync_log_lines` (
`uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`sync_log_uuid` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`exception_time` timestamp NULL DEFAULT NULL,
`exception_message` mediumtext COLLATE utf8mb4_unicode_ci,
`exception_file` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`exception_line` int(10) unsigned DEFAULT NULL,
`failure_reason` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`csv_file_row_count` int(10) unsigned DEFAULT NULL,
`csv_file_row_sequence` int(10) unsigned DEFAULT NULL,
`csv_file_row_content` mediumtext COLLATE utf8mb4_unicode_ci,
`csv_file_source` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`uuid`),
KEY `sync_log_lines_sync_log_uuid_index` (`sync_log_uuid`),
KEY `sync_log_lines_exception_time_index` (`exception_time`),
CONSTRAINT `sync_log_lines_sync_log_uuid_foreign` FOREIGN KEY (`sync_log_uuid`) REFERENCES `sync_logs` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
一次“同步”操作可将150k条记录插入该表。中的每条记录 sync_log_lines
是无法插入或更新到其专用表中的单个csv行。
所以下面我使用的查询可能会迅速升级。
select `uuid`, `sync_log_uuid`, `exception_time`, `exception_message`, `failure_reason`, `csv_file_row_count`, `csv_file_row_sequence`, `csv_file_row_content`
from `sync_log_lines`
where `sync_log_uuid` = '56b0a3b1-dab4-4343-9f9b-a2a8f075c21a'
order by `exception_time` desc
limit 100 offset 6000;
总共有15万张唱片 sync_log_uuid
= 56b0a3b1-dab4-4343-9f9b-a2a8f075c21a
. 没有 order by
先给我几毫秒 100
记录。
当我加上 order by
如上所述,它的速度减慢到30-45秒。
我知道,我知道。我做了一项研究,我完全明白:
当我在没有order by-limit 100的情况下运行查询时,它工作得非常好-它在前100条记录之后停止查询,任何100条记录
但是
当我添加order时,mysql首先将所有记录发送到临时表,然后对其排序,然后返回100条正确的记录
这绝对有道理。在巨大的数据集上,它的工作方式与预期一致。但我已经到了不知道如何优化的地步。我不能缩小日期( exception_time
)因为所有 log lines
为了这个 UUID
在2小时内插入-这是大约同步时间。
我的查询用作分页的一部分,有时用户必须查看第212页(!)这个特别的同步。
还有改进的空间吗?综合指数?别的?
2条答案
按热度按时间mbskvtky1#
在sync\u log\u uuid和exception\u time上创建1个索引。
对于mysql来说,如果不按order-by,查找前100条记录很快就会完成,因为它可以返回找到的前100条记录。
如果您通过异常订购,mysql必须读取sync\u log\u uuid='56b0a3b1-dab4-4343-9f9b-a2a8f075c21a'的所有记录,以确定哪些记录是前100条记录。
lnlaulya2#
尝试使用复合索引也称为多列索引。它将提供更好的性能。如上所述,回答创建索引http://www.mysqltutorial.org/mysql-index/mysql-composite-index/