我有以下查询:
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
使用order by时,此查询运行速度非常慢。 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
使用解释这个,DOES使用索引进行排序并返回响应,只需使用filesort所需的一小部分。所以我已经解决了#34;我的问题,但我不明白为什么SQL会根据解决方案做出不同的选择。据我所知,我只是将结果包装好,并在一个看似多余的陈述中询问所有结果...
编辑:在使用冗余子查询时,我仍然没有意识到为什么优化器开始在created_at上使用索引,但在某些情况下它并不快。我现在已经开始使用解决方案添加语句" FORCE INDEX FOR ORDER BY created_at_index_name"。
答案 0 :(得分:1)
不要使用IN ( SELECT ... )
;将其转换为JOIN
。或者转换为EXISTS ( SELECT ... )
可能会更好地优化。
请提供EXPLAINs
。 即使它们都是相同的。如果您的版本有此版本,请提供EXPLAIN FORMAT=JSON SELECT ...
。
如果优化器被嵌套查询混淆,为什么要添加另一个嵌套?
哪个表格是users
?
您提及user.id
,但user
或FROM
中没有JOIN
表。
您使用的是什么版本的MySQL(或MariaDB)? 5.6和特别是5.7在优化器方面与MariaDB有显着差异。
请为查询中提到的每个表提供SHOW CREATE TABLE
。
您的评论中有一些提示,即您提出的查询不是给您带来麻烦的问题。请不要询问不是本身的查询来证明问题。
哦,是users.name
吗?需要查看CREATE TABLEs
以查看您是否有合适的索引。
由于提到了MariaDB,我正在添加该标记。 (这可能是让涉及特定MariaDB专业知识的人的唯一途径。)