2016-05-17 151 views
0

我有38k行的表,我使用這個查詢來比較項目表中的項目標識與來自posting_domains表的項目標識。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 

這個查詢了787-8。我不知道我的查詢是否有問題,或者我的mysql配置不當。由Laravel關係產生像

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

哪些列在您的表中有索引? – Webeng

+0

只是在每個表上的id列 – user3233336

+0

我在張貼的表上添加了索引,現在比156ms快得多。謝謝! – user3233336

回答

0

相關子查詢此查詢可以是相當緩慢的(因爲它們通常在外部查詢的每一行重複執行,一次),這可能更快。

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'在你的問題的查詢中是一個錯字。 _您可以將我的第一個建議中的子查詢想象爲「exists」集合中所有item_id值的列表._ – Uueerdo