2

我正在运行 CMS,但这与它无关。

我有一个简单的查询是:

UPDATE e107_online SET `online_location` = 'http://page.com/something.php?', `online_pagecount` = 133 WHERE `online_ip` = '175.44.*.*' AND `online_user_id` = '0' LIMIT 1;

但是我的网站支持报告的相同查询给出了:

User@Host: cosyclim_website[cosyclim_website] @ localhost [] 

Thread_id: 7493739 Schema: cosyclim_website 

Query_time: 12.883518 Lock_time: 0.000028 Rows_sent: 0 Rows_examined: 0 Rows_affected: 1 Rows_read: 1

一个简单的更新查询需要 12(几乎 13)秒?有没有办法以某种方式优化它?如果我通过 PhpMyAdmin 运行它需要 0.0003 秒。

桌子:

CREATE TABLE IF NOT EXISTS `e107_online` (
  `online_timestamp` int(10) unsigned NOT NULL default '0',
  `online_flag` tinyint(3) unsigned NOT NULL default '0',
  `online_user_id` varchar(100) NOT NULL default '',
  `online_ip` varchar(15) NOT NULL default '',
  `online_location` varchar(255) NOT NULL default '',
  `online_pagecount` tinyint(3) unsigned NOT NULL default '0',
  `online_active` int(10) unsigned NOT NULL default '0',
  KEY `online_ip` (`online_ip`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
4

2 回答 2

3

您的查询正在更新满足特定条件的一行:

UPDATE e107_online
    SET `online_location` = 'http://page.com/something.php?', `online_pagecount` = 133
    WHERE `online_ip` = '175.44.*.*' AND `online_user_id` = '0'
    LIMIT 1;

鉴于您有 IP 地址,我猜这个表相当大。数百万和数百万行。更新可能需要很长时间的原因有很多,例如服务器负载、阻塞事务和日志文件性能。在这种情况下,让我们假设问题是找到其中一行。您可以通过select在相同条件下执行 a 来测试这一点,看看需要多长时间。

假设select一直很慢,那么问题可能可以通过索引来解决。如果表没有索引——或者如果 MySQL 不能使用现有索引——那么它需要进行全表扫描。而且,可能匹配的一条记录在表的末尾。需要一段时间才能找到它。

我建议在其中一个上添加一个索引,e107_online(online_ip)或者e107_online(online_user_id, online_ip)帮助它更快地找到记录。索引需要是 b 树索引,如此所述。

使用索引的一个后果是匹配值最低的 ip 可能会被选中。我不知道这种缺乏随机性是否会对您的应用程序产生影响。

于 2013-05-18T13:53:57.007 回答
0

只是这个查询很慢,还是来自您网站的查询通常较慢?phpMyAdmin 很可能直接在您的数据库所在的机器上运行查询,这意味着网络延迟实际上是 0 毫秒。我会建议在 WHERE 子句中添加一个包含两列的索引,但 <50 行没有任何意义。这将归结为您的网站和数据库服务器之间的阻塞。

还要确保你没有做任何愚蠢的事情,比如在没有打开连接池的情况下运行(或不必要地创建大量连接)。我已经看到空间不足的连接池会导致类似的问题。

于 2013-05-19T02:28:57.163 回答