2017-12-27 242 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專業知識的人的唯一方法。)

相關問題