我有一个名为“roomlogs”的大表,它有将近100万个条目。表的结构:
id-->主键
roomid-->varchar fk到rooms表
userid-->varchar fk to users表
输入时间-->日期和时间
exittime-->日期和时间
状态-->布尔
我以前在roomid上做过索引,最近在userid列上添加了索引。
所以,当我用下面的代码运行存储过程时,它需要更多的时间,比如平均50秒。这是不应该的。
DELIMITER ;;
CREATE DEFINER=`root`@`%` PROCEDURE `enter_room`(IN pRoomId varchar(200), IN puserId varchar(50), IN ptime datetime, IN phidden int, pcheckid int, pexit datetime)
begin
update roomlogs set
roomlogs.exitTime = ptime,
roomlogs.`status` = 1
where
roomlogs.userId = puserId
and roomlogs.`status` = 0
and DATEDIFF(ptime,roomlogs.enterTime) = 0;
INSERT into roomlogs
( roomlogs.roomId,
roomlogs.userId,
roomlogs.enterTime,
roomlogs.exitTime,
roomlogs.hidden,
roomlogs.checkinId )
value
( pRoomId,
userId,
ptime,
pexit,
phidden,
pcheckid);
select *
from
roomlogs
where
roomlogs.id= LAST_INSERT_ID();
end ;;
DELIMITER ;
为什么要花这么多时间:
我最近添加了一个索引,所以前面的行没有索引。
目前没有为任何索引选择存储类型。我应该把它改成b树吗?
在我的网站上,我得到20-30对其他程序的同时调用,而这个程序有10-20个同时调用,程序中的更新查询是否锁定?但是在mysql.slow\u logs表中,每个查询的锁时间都显示为0。
这种行为还有其他原因吗?
编辑:以下是显示表格:
CREATE TABLE `roomlogs` (
`roomId` varchar(200) CHARACTER SET latin1 DEFAULT NULL,
`userID` varchar(50) CHARACTER SET latin1 DEFAULT NULL,
`enterTime` datetime DEFAULT NULL,
`exitTime` datetime DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`status` int(11) DEFAULT '0',
`hidden` int(11) DEFAULT '0',
`checkinId` int(11) DEFAULT '-1',
PRIMARY KEY (`id`),
KEY `RoomLogIndex` (`roomId`),
KEY `RoomLogIDIndex` (`id`),
KEY `USERID` (`userID`)
) ENGINE=InnoDB AUTO_INCREMENT=1064216 DEFAULT CHARSET=utf8
我还可以看到这个查询的运行次数越来越多,比如每天100000次(几乎是连续的)。
SELECT count(*) from roomlogs where roomId=proomId and status='0';
因为这个查询是从同一个表中读取的,所以innodb会在update查询上阻塞或创建锁吗?因为我可以看到,当上面的存储过程运行更多次时,这个查询会花费更多的时间。
以下是mysql变量的链接:https://docs.google.com/document/d/17_mvau4yvpqfvdt83yhsjklhsgyd-z2mg6x7gwvyzge/edit?usp=sharing
1条答案
按热度按时间lokaqttq1#
roomlogs
需要此“综合”索引:我最近添加了一个索引,所以前面的行没有索引。
不是真的。添加
INDEX
索引整个表。默认索引类型为
BTree
; 无需明确指定。过程中的update查询是否锁定?
它可以进行某种形式的锁定。它的价值是什么
autocommit
? 你明确使用BEGIN
以及COMMIT
? table在哪ENGINE=InnoDB
? 请提供SHOW CREATE TABLE
.slow\u logs表对于每个查询,lock\u time显示为0。
这个
INSERT
您的节目似乎插入了与UPDATE
. 也许你需要INSERT ... ON DUPLICATE KEY UPDATE ...
?不要“在函数中隐藏索引列”;而不是
DATEDIFF(roomlogs.enterTime,NOW()) = 0
,做这样可以更充分地使用索引。
仅97517568中的缓冲池—使其更像9g。