首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL提高效率:限制FILESORT的数量

SQL提高效率:限制FILESORT的数量
EN

Stack Overflow用户
提问于 2017-02-11 03:10:19
回答 2查看 143关注 0票数 0

我将用这样的查询来解释一下:(post_id=主,blog_id=index )

代码语言:javascript
复制
SELECT post_id FROM posts WHERE blog_id IN (2,3,...) ORDER BY post_id DESC LIMIT 10

更新: IN()中的ids可能很多。如果DB使用blog_id作为查询的键,它必须进行文件排序,因为索引将如下所示:

代码语言:javascript
复制
(blog_id,post_id)-> (1,55) (1,59) (1,69) (2,57) (2,71) (2,72) (3,12)

如果您只搜索一个id blog_id = 2而不是IN(),则不需要执行任何文件排序,因为所有匹配都已经按顺序进行了。

问题是,我认为它正在发生,不是100%确定,只是通过查看查询执行时间,如果我添加一个限制10,有效的方法是只捕获和文件排序每个blog_id索引键匹配的最后10个IN,也许它已经这样做了,但看起来像IN (2,3,4) ORDER BY post_id DESC LIMIT 10,它将文件排序数千个IN而不是30个。

我希望我是大错特错的,因为如果我错了,那将是一个可怕的低效错误。如果我是对的,有没有什么我可以做的引擎或改变?甚至可以更改数据库。目前我在10.1.13-MariaDB上,表是InnoDB

EN

回答 2

Stack Overflow用户

发布于 2017-02-11 03:12:54

不幸的是,MySQL没有可以让你做你想做的事情的索引。

但是,您可以重写已有的查询并使用现有索引:

代码语言:javascript
复制
SELECT p.post_id
FROM ((SELECT post_id
       FROM posts
       WHERE blog_id = 2
       ORDER BY post_id DESC
       LIMIT 10
      ) UNION ALL
      (SELECT post_id
       FROM posts
       WHERE blog_id = 3
       ORDER BY post_id DESC
       LIMIT 10
      )
     ) p
ORDER BY post_id DESC
LIMIT 10;

每个子查询都将使用索引。对20个元素进行排序是相当快的。

票数 2
EN

Stack Overflow用户

发布于 2017-02-11 09:07:08

看看EXPLAIN SELECT ...;看看它是否显示“文件排序”。

执行以下操作以获取详细信息,即使是小数据集也是如此:

代码语言:javascript
复制
FLUSH STATUS;
SELECT ...;
SHOW SESSION STATUS LIKE 'Handler%';

您确实需要INDEX(blog_id, post_id)。如果您使用的是InnoDB,并且该表具有

代码语言:javascript
复制
PRIMARY KEY(post_id),
INDEX(blog_id)

那么你就有了这个综合指数。这是因为每个二级索引都隐式包含主键的列。

既然您正在使用MariaDB,那么看看是否会做您询问的另一件事。

当优化器看到这一点时:

代码语言:javascript
复制
WHERE blog_id IN (2,3)
ORDER BY post_id DESC LIMIT 10

它同时拥有INDEX(blog_id)INDEX(post_id),它根据有限的统计数据做出决定,决定走哪条路:

计划A:根据blog_id +文件排序进行过滤,或者

计划B:按post_id顺序扫描,希望很快找到10行。

任何一个都是有风险的。计划A,如果大多数或所有行都是(2,3),将有一个大排序。当匹配行少于10行时,计划B将扫描整个表(或索引)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42166944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档