2017-12-27 111 views
2

我有以下查询:mysql命令由品牌查询慢解决了,但是不知道为什么

select * 
from 
    `twitter_posts` 
where 
    `main_handle_id` in (
    select 
     `twitter`.`main_handle_id` 
    from 
     `users` 
     inner join `twitter` on `twitter`.`user_id` = `user`.`id` 
    where 
     `users` LIKE 'foo' 
) 
order by created_at 

当使用顺序由该查询运行显着变慢。 twitter_posts表的索引位于created_at时间戳和main_handle_id列。

我用“解释”来看引擎正在计划做什么,并注意到一个文件夹......我不期望看到这个文件夹作为索引存在于twitter_posts表中。在浏览覆盖Stackoverflow和博客上的各种帖子后,没有任何示例适用于我。我有一种预感,也许,sql优化器与嵌套选择有些混淆。所以我包裹查询,并通过created_at下令的结果:

select * (select * 
from 
    `twitter_posts` 
where 
    `main_handle_id` in (
    select 
     `twitter`.`main_handle_id` 
    from 
     `users` 
     inner join `twitter` on `twitter`.`user_id` = `user`.`id` 
    where 
     `users` LIKE 'foo' 
) 
) 
order by created_at 

使用这一个解释,是否使用索引进行排序,并返回在它与文件排序需要一小部分的响应。所以我“解决了”我的问题,但我不明白为什么SQL会根据解决方案做出不同的选择。据我所知,我只是包装的结果,并要求一切看起来多余的声明...

编辑:我仍然不知道为什么优化器开始使用created_at上的索引当使用冗余子查询时,但在某些情况下不会更快。我现在用解决方案来添加语句“FORCE INDEX FOR ORDER BY created_at_index_name”。

+0

您是否尝试过使用强制索引? –

+0

我有,但是这也不起作用+这是一个肮脏的解决方案...虽然冗余查询也是如此:)所以我的问题不是如何优化这个解决方案。我的问题是为什么。我认为答案很可能取决于我使用的MariaDB版本。我不知道MySQL和Maria之间有任何显着的优化变化... –

+0

@PraveenE我已经更新了我的答案,使用冗余选择会导致在某些查询中创建临时表(取决于内部的位置声明)也使其缓慢。 –

回答

1

请勿使用IN (SELECT ...);将其转换为JOIN。或者也许转换为EXISTS (SELECT ...)可能会优化得更好。请致电EXPLAINs即使它们都是相同的。如果你的版本有这样的话,请提供EXPLAIN FORMAT=JSON SELECT ...

如果优化器被嵌套查询困惑,为什么要添加另一个嵌套?

哪个表是users

您提到user.id,但FROMJOIN中没有user表。

你使用的是什么版本的MySQL(或MariaDB)? 5.6,尤其是5.7在优化器方面与MariaDB相比具有显着差异。

请为查询中提到的每个表提供SHOW CREATE TABLE

在您的评论中有提示,您提出的查询不是给您带来麻烦的提示。请不要询问本身的问题

哦,是users.name?需要查看CREATE TABLEs以查看您是否有合适的索引。

由于MariaDB被提及,我添加了该标签。 (这可能是获得具体涉及MariaDB专业知识的人的唯一方法。)

相关问题