Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何使用“更新SQL查询”优化更新SQL查询;如果不在(…超过1000项…)中;?_Mysql_Sql_Query Performance - Fatal编程技术网

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建议的两个更新都放在事务中。没有其他人会看到表的中间状态。