如何优化 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)。清理你的索引!他们减慢了更新速度。