【问题标题】:How do I speed up a sql query searching from two tables?如何加快从两个表中搜索的 sql 查询?
【发布时间】:2017-03-07 16:07:23
【问题描述】:

这是一个例子,所以我有表user和表city,它们是这样的:

user 列是(user_id、city_id、timestamp)[user_id 和 city_id 是唯一的]

city 列是 (city_name, city_id) [city_id 是唯一的]

我想从某个城市获取给定日期的用户数,所以基本上我是这样做的:

select city_id, city_name, 
    (select count(user.user_id) 
     from user, city 
     where DATE_FORMAT(user.timestamp, '%Y-%m-%d') = '2017-03-07' 
     and user.city_id = ct.city_id) as user_count
from city ct 
where (city_id = 20 or city_id = 30)

结果:

city_id, city_name, user_count
20       New York   100
30       LA         200

然后我意识到这比直接搜索要慢得多

select count(user.user_id) 
from user, city 
where DATE_FORMAT(user.timestamp, '%Y-%m-%d') = '2017-03-07' 
    and user.city_id = 20

这是为什么?原始搜索中的ct.city_id 不是已经设置为20 还是30?我应该如何优化搜索并获得我想要的表格格式的结果?

【问题讨论】:

  • 这些表有索引吗?
  • 您的第二个查询与第一个查询相同。第二个查询正在执行CROSS JOIN,而第一个查询正在执行INNER JOIN。这种类型的隐式JOIN 语法也已被over 25 years 弃用。您应该使用明确的JOINs。如果需要,它们更干净、更清晰,并且更容易转换为 OUTER JOINs。

标签: mysql sql


【解决方案1】:

您可以改进您的查询,避免子选择并使用内部联接和分组方式

select city_id, city_name,    count(user.user_id) 
from user
inner join city on user.city_id = city.city_id
where DATE_FORMAT(user.timestamp, '%Y-%m-%d') = '2017-03-07' 
and city_id in (city_id = 20 or city_id = 30)
group by city_id, city_name

【讨论】:

    【解决方案2】:

    我会假设 MySQL 在第一个查询中选择将您的派生表具体化为一个内部临时表,并且不会在您的第二个查询中做出该选择。

    对于派生表(FROM 子句中的子查询),优化器有以下选择:

    • 将派生表合并到外部查询块中
    • 将派生表具体化为内部临时表

    来源:Mysql Documentation - 8.2.2 Optimizing Subqueries, Derived Tables, and Views

    【讨论】:

      【解决方案3】:

      试试这个:

      select city_id, city_name, count(user.user_id) as user_count
      from city ct 
      inner join user on user.city_id = ct.city_id
      where (ct.city_id = 20 or ct.city_id = 30)
      AND DATE_FORMAT(user.timestamp, '%Y-%m-%d') = '2017-03-07'
      

      【讨论】:

        猜你喜欢
        • 2012-05-01
        • 1970-01-01
        • 2013-06-25
        • 1970-01-01
        • 2017-01-03
        • 1970-01-01
        • 2018-12-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多