2016-05-17 4 views
0

Ich habe Tabelle mit 38k Zeilen und ich verwende diese Abfrage, um Artikel-ID aus Artikel Tabelle mit Artikel-ID aus Posted_domains Tabelle zu vergleichen.Mysql lange Ausführungsabfrage

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 

Diese Abfrage nahm 8s. Ich weiß nicht, ob ein Problem mit meiner Abfrage oder mein mysql ist falsch konfiguriert. Diese Abfrage von Laravel Beziehungen wie

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

Welche Spalten haben Indizes in Ihrer Tabelle? – Webeng

+0

nur ID-Spalte auf jeder Tabelle – user3233336

+0

Ich habe Indizes auf gepostete Tabelle hinzugefügt und jetzt ist viel schneller 156ms. Vielen Dank! – user3233336

Antwort

0

korrelieren Unterabfragen sein kann ziemlich langsam erzeugt wird (wie sie oft wiederholt ausgeführt werden, einmal für jede Zeile in der äußeren Abfrage), diese könnte schneller sein.

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 

ich sagen Macht weil Subqueries wo sind auch eher langsam in MySQL.

Dieser LINKE JOIN wird wahrscheinlich der schnellste sein.

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; 

Da es ein keine ist Szenario passt, es ist technisch nicht einmal brauchen eine Unterabfrage zu sein; und könnte als direkter linker Join schneller sein, aber das hängt von Indizes und möglicherweise tatsächlichen Datenwerten ab.

+0

Ich denke ** und item_id nicht in ** es war ein falscher Tippfehler in der ersten Abfrage richtig? Die Abfrage ist sehr schnell. – user3233336

+0

@ user3233336 kein Tippfehler, es sei denn 'NOT EXISTS' war ein Tippfehler in der Frage in Ihrer Frage. Sie können sich die Unterabfrage in meinem ersten Vorschlag als eine Liste aller item_id-Werte in der "exists" -Sammlung vorstellen. – Uueerdo

Verwandte Themen