如何优化 order by 和 limit?
How to optimize order by and limit?
我有一个客户希望我为他的网站做一个后端。他需要 table 显示所有带分页的文件。
CREATE TABLE `content_files` (
`id` varchar(16) NOT NULL,
`owner` varchar(16) DEFAULT NULL,
`location` varchar(16) NOT NULL,
`parent` varchar(16) DEFAULT NULL,
`date` int(11) NOT NULL,
`filename` varchar(256) NOT NULL,
`username` varchar(64) NOT NULL,
`email` varchar(256) NOT NULL,
`ip` varchar(15) NOT NULL,
`json` text NOT NULL,
`bin` blob NOT NULL
);
ALTER TABLE `content_files`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `ID` (`id`),
ADD KEY `id_2` (`id`),
ADD KEY `date` (`date`),
ADD KEY `filename` (`filename`(255)),
ADD KEY `username` (`username`(63)),
ADD KEY `email` (`email`(255)),
ADD KEY `ip` (`ip`(14));
需要排序的项目table是日期、文件名、用户名、电子邮件和ip。目前有 65,000 条记录。如果限制很高,正如预期的那样,它需要更长的时间,但要长得多。 100 秒获得第 60,000 个条目。
我只是在使用:
SELECT id, date, filename, username, email ip
FROM content_files
ORDER BY filename
LIMIT 60000, 20
我搜索了这个问题,但是 none 的提示似乎改善了我的查询。我在他的模式中遗漏了一些明显的错误吗?我该如何优化它?
您正在构建一个大数据集并对其进行排序,只是为了丢弃 6 万行并显示 20 行。这项工作可以通过所谓的延迟连接来减少。排序仍然必须进行,但它可以占用更少的内存,因此速度更快。
编辑 将子查询加入连接。
SELECT a.id, a.date, a.filename, a.username, a.email ip
FROM content_files a
JOIN ( SELECT id
FROM content_files
ORDER BY filename
LIMIT 60000, 20
) b ON a.id = b.id
ORDER BY a.filename
这对你的大排序很重要 - 在较小的数据集上进行丢弃操作。然后,它仅查找 20 行所需的所有数据。
最后,如果您在 (filename, id)
上添加复合索引,则可以通过扫描索引来满足子查询,这将使它更快。您可以在创建复合索引时删除 filename
上的索引。
您的 table 上有一堆冗余索引。 (三个单独 id
)。清理你的索引!他们减慢了更新速度。
我有一个客户希望我为他的网站做一个后端。他需要 table 显示所有带分页的文件。
CREATE TABLE `content_files` (
`id` varchar(16) NOT NULL,
`owner` varchar(16) DEFAULT NULL,
`location` varchar(16) NOT NULL,
`parent` varchar(16) DEFAULT NULL,
`date` int(11) NOT NULL,
`filename` varchar(256) NOT NULL,
`username` varchar(64) NOT NULL,
`email` varchar(256) NOT NULL,
`ip` varchar(15) NOT NULL,
`json` text NOT NULL,
`bin` blob NOT NULL
);
ALTER TABLE `content_files`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `ID` (`id`),
ADD KEY `id_2` (`id`),
ADD KEY `date` (`date`),
ADD KEY `filename` (`filename`(255)),
ADD KEY `username` (`username`(63)),
ADD KEY `email` (`email`(255)),
ADD KEY `ip` (`ip`(14));
需要排序的项目table是日期、文件名、用户名、电子邮件和ip。目前有 65,000 条记录。如果限制很高,正如预期的那样,它需要更长的时间,但要长得多。 100 秒获得第 60,000 个条目。
我只是在使用:
SELECT id, date, filename, username, email ip
FROM content_files
ORDER BY filename
LIMIT 60000, 20
我搜索了这个问题,但是 none 的提示似乎改善了我的查询。我在他的模式中遗漏了一些明显的错误吗?我该如何优化它?
您正在构建一个大数据集并对其进行排序,只是为了丢弃 6 万行并显示 20 行。这项工作可以通过所谓的延迟连接来减少。排序仍然必须进行,但它可以占用更少的内存,因此速度更快。
编辑 将子查询加入连接。
SELECT a.id, a.date, a.filename, a.username, a.email ip
FROM content_files a
JOIN ( SELECT id
FROM content_files
ORDER BY filename
LIMIT 60000, 20
) b ON a.id = b.id
ORDER BY a.filename
这对你的大排序很重要 - 在较小的数据集上进行丢弃操作。然后,它仅查找 20 行所需的所有数据。
最后,如果您在 (filename, id)
上添加复合索引,则可以通过扫描索引来满足子查询,这将使它更快。您可以在创建复合索引时删除 filename
上的索引。
您的 table 上有一堆冗余索引。 (三个单独 id
)。清理你的索引!他们减慢了更新速度。