Mysql 如何使用“更新SQL查询”优化更新SQL查询;如果不在(…超过1000项…)中;?
我有一个包含以下字段的表:Mysql 如何使用“更新SQL查询”优化更新SQL查询;如果不在(…超过1000项…)中;?,mysql,sql,query-performance,Mysql,Sql,Query Performance,我有一个包含以下字段的表:ID,用户名,数据,是在线的。每分钟我都会收到来自远程服务器的大部分新数据,这些数据都来自当前在线用户[(用户名,is_online,data),…] 我需要设置IS_ONLINE=1仅用于此数组中的用户,对于其他用户,设置IS_ONLINE=0。 在循环i中,进行查询更新用户集是\u online=1,data='data',其中username='username'。然后对集合IS_ONLINE=0执行以下查询: 更新用户集为\u online=0,其中用户名不在(
ID
,用户名
,数据
,是在线的
。每分钟我都会收到来自远程服务器的大部分新数据,这些数据都来自当前在线用户[(用户名,is_online,data),…]
我需要设置IS_ONLINE=1
仅用于此数组中的用户,对于其他用户,设置IS_ONLINE=0
。
在循环i中,进行查询更新用户集是\u online=1,data='data',其中username='username'
。然后对集合IS_ONLINE=0
执行以下查询:
更新用户集为\u online=0,其中用户名不在('user1','user2',…,'user1000')
若我有少量的用户,它运行得很好,但若users表包含超过100000行,则此查询执行时间超过50秒
请您给我一个答案或想法,我可以如何提高这个简单的查询速度
谢谢大家! 当前,
不在
查询涉及整个100000行。让我们通过更改查询和模式来避免这种情况。与其为所有用户设置is_online
,不如设计一种方法,让您只需触摸当前在线的用户
与其让is\u online
成为布尔值,不如让它成为DATETIME
或BIGINT
。然后为在线的用户设置一个新的、更高的值,忽略其他用户
这需要另外一点信息——新的高值。只需将其存储在另一个表中,该表只包含一行和一列
该模式避免了注释中的时间戳混淆。唯一“在线”的用户是那些在is_online
中具有最新值的用户;其他的都是离线的
现在让我们检查模式的其余部分。您真的需要id
和username
?投掷id
并使用户名
成为主键
;这将加快速度,因为它不必进行双重查找——首先查找给定用户名的id,然后访问行更新它。(注意:如果它是另一个表中的外键
,则可能会出现问题。如果是,请提供更多详细信息。)
另一个技巧——使用1000条语句来处理1000行要比使用单个查询慢得多。要对不同的值进行多次更新,请使用IODKU
我希望这一切可以归结为3条sql语句:
BEGIN;
$hv = SELECT high_value FROM HighValue FOR UPDATE;
$hv++;
INSERT INTO MainTable
VALUES
('user1', 'blah1', $hv),
('user2', 'blah2', $hv),
...
ON DUPLICATE KEY UPDATE
data = VALUES(data), -- sets the new `data` value
is_online = $hv ;
UPDATE HighValue SET high_value = $hv;
COMMIT;
. . 更新行需要时间——锁定、记录等等。50秒?这是不错的表现哦。。。你不能把那些用户名放到一个表中吗?然后你可以
JOIN
到那个表中,你会立即完成。更新用户设置需要多长时间?开始时可能更快,然后标记在线用户,使用似乎不需要太长时间的过程。将@EricBrandt建议的两个更新都放在事务中。没有其他人会看到表的中间状态。