以下是一个示例,所以我有表user
和表city
,他们是这样的:
user
列是(user_id,city_id,时间戳) [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?我应该如何优化搜索并以我想要的表格格式获得结果?
答案 0 :(得分:6)
您可以改进查询,避免使用内部联接和分组
进行子选择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
答案 1 :(得分:0)
我会假设MySQL选择在第一个查询中将派生表实现为内部临时表,并且不会对第二个查询做出选择。
对于派生表(FROM子句中的子查询),优化器有以下选择:
- 将派生表合并到外部查询块
- 将派生表具体化为内部临时表
来源:Mysql Documentation - 8.2.2 Optimizing Subqueries, Derived Tables, and Views
答案 2 :(得分:0)
试试这个:
private CancellationTokenSource cts;
public async void MyButtonhandler(object sender, EventArgs e) {
cts = new CancellationTokenSource();
try {
var result = await Task.Run(() => ReadAll(cts));
if (result) {
//success
} else {
//failure
}
} catch (TaskCanceledException ex) {
}
}
internal async Task<bool> ReadAll(CancellationTokenSource cts) {
byte[] data = new byte[1];
var timeout = TimeSpan.FromSeconds(10);
var ReadAllTask = Task.Run(() => {
// Read all information
// [omit communication exchange via COM port]
}, cts.Token);
if (await Task.WhenAny(ReadAllTask, Task.Delay(timeout)) == ReadAllTask) {
return true;
}
cts.Cancel();
return false;
}