2016-05-17 39 views
0

私は38k行のテーブルを持っています。このクエリを使用してitemsテーブルのアイテムIDとposted_domainsテーブルのアイテムIDを比較します。Mysql実行時間の長いクエリ

select * from `items` 
where `items`.`source_id` = 2 and `items`.`source_id` is not null 
    and not exists (select * 
        from `posted_domains` 
        where `posted_domains`.`item_id` = `items`.`id` and `domain_id` = 1) 
order by `item_created_at` asc limit 1 

このクエリは、8Sを取りました。クエリに問題があるのか​​、mysqlが正しく設定されていないのか分かりません。 (それらはしばしば外部クエリ内の行ごとに一度、繰り返し実行されるように)このクエリはかなり遅くなることが

$items->doesntHave('posted', 'and', function ($q) use ($domain) { 
    $q->where('domain_id', $domain->id); 
}); 
+0

どの列にテーブルのインデックスがありますか? – Webeng

+0

各テーブルのID列は – user3233336

+0

投稿されたテーブルにインデックスを追加しましたが、今ははるかに高速です156ms。ありがとう! – user3233336

答えて

0

相関サブクエリようLaravel関係によって生成され、この速いかもしれません。

select * 
from `items` 
where `items`.`source_id` = 2 
    and `items`.`source_id` is not null 
    and item_id not in (
     select DISTINCT item_id 
     from `posted_domains` 
     where `domain_id` = 1) 
order by `item_created_at` asc 
limit 1 

でのサブクエリは、MySQLでもかなり遅いので。私はかもしれないを言います

このLEFT JOINがおそらく最も速くなります。

select * 
from `items` 
LEFT JOIN (
     select DISTINCT item_id 
     from `posted_domains` 
     where `domain_id` = 1) AS subQ 
ON items.item_id = subQ.item_id 
where `items`.`source_id` = 2 
    and `items`.`source_id` is not null 
    and subQ.item_id is null 
order by `item_created_at` asc 
limit 1; 

それはいないがシナリオに一致しているので、それは技術的にも、サブクエリである必要はありません。ダイレクト・レフト・ジョインとしては高速かもしれませんが、それは索引や場合によっては実際のデータ値に依存します。

+0

私は**とitem_idは**最初のクエリの誤ったタイプミスではないと思いますか?クエリは非常に高速です。 – user3233336

+0

@ user3233336あなたの質問に「NOT EXISTS」が誤って入力されていない限り、タイプミスではありません。 _私の最初の提案のサブクエリは、「存在する」セット内のすべてのitem_id値のリストとして考えることができます。 – Uueerdo

関連する問題