2016-05-17 98 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