Java 执行此SQL查询的更有效方法?时间比较查询?
我有一个SQL查询,它每5秒查询一次数据库,以确定当前正在使用该软件的用户。活动用户已在过去10秒内ping服务器。(该表在用户活动时得到正确更新,并且在会话超时时有一个线程逐出条目,这一切都正常工作) 我想要的是一种更高效/更快的方法,因为它经常被调用,大约每5秒调用一次。此外,数据库中最多可能有500个用户。语言是Java,但问题确实涉及任何语言Java 执行此SQL查询的更有效方法?时间比较查询?,java,mysql,sql,Java,Mysql,Sql,我有一个SQL查询,它每5秒查询一次数据库,以确定当前正在使用该软件的用户。活动用户已在过去10秒内ping服务器。(该表在用户活动时得到正确更新,并且在会话超时时有一个线程逐出条目,这一切都正常工作) 我想要的是一种更高效/更快的方法,因为它经常被调用,大约每5秒调用一次。此外,数据库中最多可能有500个用户。语言是Java,但问题确实涉及任何语言 List<String> r = new ArrayList<String>(); Calendar c = Calen
List<String> r = new ArrayList<String>();
Calendar c = Calendar.getInstance();
long threshold = c.get(Calendar.SECOND) + c.get(Calendar.MINUTE)*60 + c.get(Calendar.HOUR_OF_DAY)*60*60 - 10;
String tmpSql = "SELECT user_name, EXTRACT(HOUR FROM last_access_ts) as hour, EXTRACT(MINUTE FROM last_access_ts) as minute, EXTRACT(SECOND FROM last_access_ts) as second FROM user_sessions";
DBResult rs = DB.select(tmpSql);
for (int i=0; i<rs.size(); i++)
{
Map<String, Object> result = rs.get(i);
long hour = (Long)result.get("hour");
long minute = (Long)result.get("minute");
long second = (Long)result.get("second");
if (hour*60*60 + minute*60 + second > threshold)
r.add(result.get("user_name").toString());
}
return r;
List r=new ArrayList();
Calendar c=Calendar.getInstance();
长阈值=c.get(日历秒)+c.get(日历分钟)*60+c.get(日历小时/天)*60*60-10;
String tmpSql=“选择用户名,提取(上次访问的小时数)作为小时,提取(上次访问的分钟数)作为分钟,提取(上次访问的秒数)作为用户会话的秒数”;
DBResult rs=DB.select(tmpSql);
对于(int i=0;i阈值)
r、 添加(result.get(“user_name”).toString());
}
返回r;
在您的选择中尝试MySQLTimeDiff
功能。这样,您可以只选择活动的结果,而不必进行任何其他计算
链接:我将把逻辑从Java移到DB。这意味着您将
if
转换为where
,只需选择有效结果的名称
从上次访问的用户会话中选择用户名?
在您的示例中,c
表示当前时间。结果很可能是空的
因此,您的问题应该更多地是关于数据库上的日期-时间操作。如果希望运行得更快,请在
用户会话(上次访问,用户名)
上创建索引,并在查询中执行日期逻辑:
select user_name
from user_sessions
where last_access_ts >= now() - 5/(24*60*60);
这确实有缺点。您可能经常更新
last\u access\t
字段。该字段上的索引也必须更新。从积极的一面来看,这是一个覆盖索引,因此索引本身可以满足查询,而无需求助于原始数据页。只需使用此查询让数据库为您进行比较:
SELECT
user_name
FROM user_sessions
where TIMESTAMPDIFF(SECOND, last_access_ts, current_timestamp) > 10
完整示例:
List<String> r = new ArrayList<String>();
Calendar c = Calendar.getInstance();
long threshold = c.get(Calendar.SECOND) + c.get(Calendar.MINUTE)*60 + c.get(Calendar.HOUR_OF_DAY)*60*60 - 10;
// this will return all users that were inactive for longer than 10 seconds
String tmpSql = "SELECT
user_name
FROM user_sessions
where TIMESTAMPDIFF(SECOND, last_access_ts, current_timestamp) > 10";
DBResult rs = DB.select(tmpSql);
for (int i=0; i<rs.size(); i++)
{
Map<String, Object> result = rs.get(i);
r.add(result.get("user_name").toString());
}
return r;
List r=new ArrayList();
Calendar c=Calendar.getInstance();
长阈值=c.get(日历秒)+c.get(日历分钟)*60+c.get(日历小时/天)*60*60-10;
//这将返回所有处于非活动状态超过10秒的用户
String tmpSql=“选择
用户名
来自用户会话
其中TIMESTAMPDIFF(第二次,最后一次访问,当前时间戳)>10”;
DBResult rs=DB.select(tmpSql);
对于(inti=0;i来说,解决方案是使用where子句从代码中删除sql查询的逻辑,以便仅从该select中获取活动用户
使用sql内置函数可以更快地在代码中获得更少的记录和迭代
将此添加到sql查询以仅获取活动用户:
Where TIMESTAMPDIFF(SECOND, last_access_ts, current_timestamp) > 10
这将为您获取日期为10秒之前或更早的所有记录。如果我没有弄错,那么您的user\u sessions
表中只有500个条目。在这种情况下,我甚至不关心索引。扔掉它们。对于如此低的记录计数,DB引擎可能无论如何都不会使用它们。由于没有更新,性能会有所提高每次记录更新的索引日期可能会高于查询开销
如果您关心数据库压力,那么如果您的应用程序允许,请将查询/更新间隔延长到1分钟或更长时间。Gordon Linoff的回答应该会为您提供最佳的查询性能
作为一个补充说明(因为它之前已经咬过我):如果你没有对所有用户回调使用相同的同步时间,那么你的“活动用户逻辑”在设计上是有缺陷的。DateDiff只在天/月/年工作,这需要小时/分钟/秒来代替TimeDiff函数。这个链接有一个例子:或