简体   繁体   English

如何加快从两个表搜索的SQL查询?

[英]How do I speed up a sql query searching from two tables?

Here's an example, so I have table user and table city , they're like this: 这是一个示例,因此我有表user和table city ,它们是这样的:

user columns are (user_id, city_id, timestamp) [user_id and city_id are unique] user列是(user_id,city_id,时间戳) [user_id和city_id是唯一的]

city columns are (city_name, city_id) [city_id is unique] city列是(city_name,city_id) [city_id是唯一的]

And I want to get user count in a given date from certain city, so basically I did it like this: 我想从特定城市获取给定日期的用户数,因此基本上我这样做是这样的:

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)

And Result: 结果:

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

Then I realized this is way slower than searching directly for 然后我意识到这比直接搜索要慢得多

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

Why is this? 为什么是这样? Isn't ct.city_id in the original search already being set as either 20 or 30? 原始搜索中的ct.city_id是否已设置为20或30? How should I optimize the search and get the result in the table format I want? 如何优化搜索并以所需的表格格式获取结果?

You could improve your query avoiding subselect and using an inner join and group by 您可以改进查询,避免子选择,而使用内部联接和分组依据

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

I am would assume that MySQL is choosing to materialize your derived table into an internal temporary table in the first query, and does not make that choice with your second query. 我假设MySQL选择在第一个查询中将派生表具体化为内部临时表,而不在第二个查询中做出选择。

For derived tables (subqueries in the FROM clause), the optimizer has these choices: 对于派生表(FROM子句中的子查询),优化器具有以下选择:

  • Merge the derived table into the outer query block 将派生表合并到外部查询块中
  • Materialize the derived table to an internal temporary table 将派生表具体化为内部临时表

source: Mysql Documentation - 8.2.2 Optimizing Subqueries, Derived Tables, and Views 来源: Mysql文档-8.2.2优化子查询,派生表和视图

Try this: 尝试这个:

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'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM