Mysql更新查询花费了很多时间

Mysql更新查询花费了很多时间,mysql,galera,Mysql,Galera,我有一个mysql表,这个表上有一列(numviews),经常更新(相同的更新查询在循环中运行)。它花费了超过2秒的大量时间,我无法找到如何改进它,因为它也影响/减慢了我的应用程序,而我的应用程序依赖于此表。这是mysql表 注意:这是一个innodb表,没有其他慢速查询。此表位于mariadb galera集群下。我的连接数也达到了300个。在任何时间点,全局连接都不会超过170/180 CREATE TABLE `data_table` ( `site` VARCHAR(100) NOT

我有一个mysql表,这个表上有一列(numviews),经常更新(相同的更新查询在循环中运行)。它花费了超过2秒的大量时间,我无法找到如何改进它,因为它也影响/减慢了我的应用程序,而我的应用程序依赖于此表。这是mysql表

注意:这是一个innodb表,没有其他慢速查询。此表位于mariadb galera集群下。我的连接数也达到了300个。在任何时间点,全局连接都不会超过170/180

CREATE TABLE `data_table` (
  `site` VARCHAR(100) NOT NULL DEFAULT '',
  `active` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
  `numclicks` INT(10) UNSIGNED NOT NULL DEFAULT '0',
  `numviews` INT(20) UNSIGNED NOT NULL DEFAULT '0',
  `country` VARCHAR(200) DEFAULT NULL,
  `viewcount` INT(10) UNSIGNED NOT NULL DEFAULT '0',
  `name` VARCHAR(150) NOT NULL DEFAULT '',
  `comments` TEXT NOT NULL,
  `boost` FLOAT DEFAULT '0',
  `daily_limit` INT(11) DEFAULT '0',
  PRIMARY KEY (`site`)
) ENGINE=INNODB DEFAULT CHARSET=latin1
下面是在循环上运行的mysql更新查询(大约是下面这个表上运行的查询的50倍)

编辑:我也可以看到一些死锁

------- TRX HAS BEEN WAITING 2 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3020 page no 10 n bits 120 index `PRIMARY` of table `data_table`trx table locks 1 total table locks 47  trx id 71211631903 lock_mode X locks rec but not gap waiting lock hold time 2 wait time before grant 0
------------------
---TRANSACTION 71211631885, ACTIVE 2 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 1083597, OS thread handle 0x7f782a335700, query id 184464304 machine1 XX.XX.XX.XX user updating
UPDATE data_table set numviews = numviews + 1 where site='xyz'
Trx #rec lock waits 12 #table lock waits 0
Trx total rec lock wait time 12 SEC
Trx total table lock wait time 0 SEC
------- TRX HAS BEEN WAITING 2 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 3020 page no 10 n bits 120 index `PRIMARY` of table `data_table` trx table locks 1 total table locks 47  trx id 71211631885 lock_mode X locks rec but not gap waiting lock hold time 2 wait time before grant 0
------------------
---TRANSACTION 71211631883, ACTIVE 2 sec
mysql tables in use 1, locked 1
2 lock struct(s), heap size 360, 1 row lock(s), undo log entries 1
MySQL thread id 1082885, OS thread handle 0x7f713e848700, query id 184464302 xxx XX.XX.XX.XX user query end
UPDATE data_table set numviews = numviews + 1 where site='xyz'
Trx #rec lock waits 225 #table lock waits 0
Trx total rec lock wait time 366 SEC
Trx total table lock wait time 0 SEC

有人能帮我改进这个更新查询吗

确保站点列有一个索引,或者如果您可以通过ID而不是名称来确定站点,则会对其进行更大的改进。创建并将ID设置为主键。此外,如果只有一个站点,您可以通过限制1对其进行一些改进。否则我不确定。如果在循环中运行,也许可以使用PDO对其进行改进,以准备具有不同值的相同请求。

实际上不需要这样做,您要做的是更新列或增加
num\u views
列。我的意思是,假设您正在循环1000次并执行
更新
;相反,执行一次值为1000的
update
,表示
set numviews=1000+1
(或者)换句话说,如果您手头有视图总数值,则可以执行一次
更新
操作。如果是这样,下面的代码也会这样做

UPDATE data_table set numviews = total_views + 1 where site='xyz';
快速变化的计数器(点击、视图)应位于单独的表中。这样,不需要这些列的查询(读写)就不会干扰它们

从任何事务中删除
UPDATE
——将其作为自己的事务处理


Galera节点之间的距离有多远?如果它们是跨国家的,比如说100毫秒,那么你每秒只能做10次这样的更新。如果这是你的情况,读我的;然后,我们可以讨论如何在Galera上使用MyISAM,以允许更高的
更新吞吐量

表中的行数?@Rahul少于1000@Strawberry是的,这是一个循环,我的意思是我只是将numviews增加1,这是一个过程。我有300最大连接也。在任何时候,全局连接都不会超过170/180。我怀疑它们是相同的@strawberry抱歉,我的错,更新了问题是,正如你所看到的,站点是主键。所以它默认有一个索引。你是对的,我现在在创建表的末尾看到了它,谢谢:)你不认为它与更新数据_table set numviews=numviews+1相同吗;运行循环,然后更新数字一次,很好的呼叫Rahul@Sthita,不,因为假设你正在循环1000次并执行更新。相反,执行一次值为1000的更新,即
set numviews=1000+1
您的查询与提问者建议的更新不同。这意味着它的作用不一样。原始更新会导致每行的数字不同。您的更新将整列
numviews
设置为一个值,这可能不是期望的结果。这没有意义。需要更多的咖啡。
UPDATE data_table set numviews = total_views + 1 where site='xyz';