我有一个名为i_visited
的MySQL表,结构如下:userid,tid,dateline
我在view_thread.php页面中运行此条件:
if (db('count','SELECT userid FROM i_visited
WHERE tid = '.intval($_GET['id']).'
AND userid = '.$user['id']))
mysql_query('UPDATE i_visited
SET dateline = unix_timestamp(now())
WHERE userid = '.$user['id'].'
AND tid = '.intval($_GET['id']));
else
mysql_query('INSERT INTO i_visited (userid,tid,dateline) VALUES
('.$user['id'].','.intval($_GET['id']).',unix_timestamp(now()))');
问题是它在80/100 ms(在Windows上)40/60(在Linux上)执行
1排受影响。 (查询以0.0707秒执行)
mysql_num_rows()
又名db('count',sql)
使用2/3 ms,因此问题在于更新和插入。
P.S。 i_visited
是一个utf8_unicode_ci(InnoDB),有没有人见过这个问题?
其他查询正常运行(2/3毫秒)
CREATE TABLE i_visited (
userid int(10) NOT NULL,
tid int(10) unsigned NOT NULL,
dateline int(10) NOT NULL,
KEY userid (userid,tid),
KEY userid_2 (userid),
KEY tid (tid) )
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
答案 0 :(得分:0)
您无需选择检查是否存在,然后选择更新或插入。
您可以像这样使用MySQL的ON DUPLICATE KEY UPDATE
功能。
$query = 'INSERT INTO
i_visited (userid,tid,dateline)
VALUES (' .
$user['id'] . ',' .
intval($_GET['id']) . ',
unix_timestamp(now()))
ON DUPLICATE KEY UPDATE
dateline = unix_timestamp(now())';
mysql_query($query);
如果现在发生KEY
冲突,此查询将插入一个新行,如果插入了重复的密钥,它将改为执行更新部分。
由于您的CREATE语句中有KEY userid (userid,tid)
,因此上述查询等同于您的if...else
阻止。
试试这个,看看是否有任何收益
您也可以使用REPLACE INTO
,因为只有指定的3列,例如
$query = 'REPLACE INTO
i_visited (userid,tid,dateline)
VALUES (' .
$user['id'] . ',' .
intval($_GET['id']) . ',
unix_timestamp(now()))';
mysql_query($query);
但我建议查看ON DUPLICATE KEY UPDATE
因为它更灵活,因为它可以用在任意列数的表上,而REPLACE INTO
只能在某些有限的情况下用作其他列还需要在REPLACE INTO
语句中不必要地填写值
答案 1 :(得分:0)
我认为(部分)问题是您的表没有明确的主键 您只声明了二级密钥。
将定义更改为:
CREATE TABLE i_visited (
userid int(10) NOT NULL,
tid int(10) unsigned NOT NULL,
dateline int(10) NOT NULL,
PRIMARY KEY userid (userid,tid), <<----------
KEY userid_2 (userid),
KEY tid (tid) )
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
如果没有定义显式主键,InnoDB就无法正常工作。