【问题标题】:Mysql long execution queryMysql长执行查询
【发布时间】:2016-09-13 21:25:24
【问题描述】:

我有一个包含 38k 行的表,我使用这个查询来比较 items 表中的 item id 和 posted_domains 表中的 item id。

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

此查询耗时 8 秒。我不知道是我的查询有问题还是我的 mysql 配置错误。此查询由 Laravel 关系生成,如

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

【问题讨论】:

  • 表中有哪些列有索引?
  • 每张桌子上只有 id 列
  • 我在张贴的表上添加了索引,现在快了 156 毫秒。谢谢!

标签: mysql sql database performance laravel-5.2


【解决方案1】:

CORRELATED 子查询可能相当慢(因为它们经常重复执行,外部查询中的每一行执行一次),这可能更快。

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 中 where 的子查询也相当慢。

这个 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;

因为它是一个不匹配的场景,它在技术上甚至不需要是一个子查询;并且作为直接左连接可能会更快,但这将取决于索引以及可能的实际数据值。

【讨论】:

  • 我认为 and item_id not in 这是第一个查询中的错字,对吧?查询速度非常快。
  • @user3233336 不是拼写错误,除非NOT EXISTS 是您的问题查询中的拼写错误。 您可以将我的第一个建议中的子查询视为“exists”集中所有 item_id 值的列表。
猜你喜欢
  • 2012-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-19
  • 2012-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多