Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.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
Php 如何加速MySQL数据库/查询?_Php_Mysql_Sql_Myisam - Fatal编程技术网

Php 如何加速MySQL数据库/查询?

Php 如何加速MySQL数据库/查询?,php,mysql,sql,myisam,Php,Mysql,Sql,Myisam,我的MySQL数据库中有两个表,users和tweets,如下所示: TABLE users ( uid int(7) NOT NULL AUTO_INCREMENT, twitter_uid int(10) NOT NULL, screen_name varchar(255) NOT NULL, `name` varchar(255) NOT NULL, tweets int(6) NOT NULL, followers_count int(7) NOT NULL,

我的MySQL数据库中有两个表,users和tweets,如下所示:

TABLE users (
  uid int(7) NOT NULL AUTO_INCREMENT,
  twitter_uid int(10) NOT NULL,
  screen_name varchar(255) NOT NULL,
  `name` varchar(255) NOT NULL,
  tweets int(6) NOT NULL,
  followers_count int(7) NOT NULL,
  statuses_count int(7) NOT NULL,
  created_at int(10) NOT NULL,
  PRIMARY KEY (uid)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

TABLE tweets (
  tweet_id int(11) NOT NULL AUTO_INCREMENT,
  `query` varchar(5) NOT NULL,
  id_str varchar(18) NOT NULL,
  created_at int(10) NOT NULL,
  from_user_id int(11) NOT NULL,
  from_user varchar(256) NOT NULL,
  `text` text NOT NULL,
  PRIMARY KEY (tweet_id),
  KEY id_str (id_str)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;
tweets表包含200多万条记录。我已将唯一用户(取自tweets.from_user)放在用户表中。它现在包含94100个用户。现在我想计算每个用户发推的数量,如下所示(在PHP中):

然而,这段代码非常慢。统计150个用户的推文大约需要5分钟。按照这个速度,所有用户大约需要3天才能完成此任务


我的问题是——我一定是遗漏了什么。也许有一个更有效的查询可能,或者我应该改变一些数据库结构?非常感谢您的帮助:)

您为所有相关属性编制了索引吗?特别是从用户应该有一个索引

第一步是向经常用作搜索条件的列添加索引。

我认为最糟糕的问题是有多个查询。这很可能比索引问题更糟糕。您应该尝试只使用一个查询

UPDATE users 
SET users.tweets = (SELECT COUNT(tweet_id) 
                    FROM tweets 
                    WHERE tweets.from_user = users.uid 
                    AND users.tweets =0
                   )

首先,我要将所有这些浓缩到一个UPDATE语句中:

UPDATE users
   SET tweets =
        ( SELECT COUNT(1)
            FROM tweets
           WHERE tweets.from_user = users.screen_name
        )
 WHERE users.tweets = 0
 LIMIT 150
;

然后我会看看指数。特别是,确保推特上有一个索引。来自用户。(有关如何在表列上创建索引的信息,请参阅。)

虽然您可以通过将这些SQL语句“压缩”成一条(如其他答案所示)来显著加快
用户的更新速度。tweets
,但当用户发出新tweet时,您会怎么做?如何知道
用户。tweets
需要再次更新

  • 一种方法是,每当从
    tweets
    表中删除或插入一行,或修改
    tweets.from_user
    时,触发更新
    users.tweets
  • 您还可以删除
    用户。tweets
    并根据需要动态统计tweets

在任何情况下,要加速
从tweets中选择COUNT(tweet\u id),其中FROM\u user='%s'
查询,您需要在{FROM\u user}上创建一个索引。由于tweet\u id不为空,
COUNT(tweet\u id)
相当于
COUNT(*)
-否则需要在{from\u user,tweet\u id}上建立一个复合索引。

+1我完全同意你的看法。在最坏的情况下,有151个
SELECT
查询和150个
UPDATE
s查询。所有这些都可以替换为1
UPDATE
.cool.:-)我不确定的一件事是他的极限。。。这是真的需要在选择,@Reveller?限制就在那里,因为整个事情的缓慢。我下载了WGET for windows并创建了一个计划任务,该任务每5分钟运行一次上述代码(以150个用户为增量),以防止Apache超过300秒超时限制:)谢谢!有了来自用户的索引和上面的查询,整个过程只用了58秒LOL.FTW!(我自己也是一名商学院学生:P)看看Quassnoi的网站,看看他的例子,也许会问他不能完全同意。第一步很可能是避免这么多查询。当然,索引也很重要。破产很可能不是这里最糟糕的问题。当然,毫无疑问,基准测试和解释可以是您的朋友。:-)考虑到90k个条目没有索引,从实践经验来看,这对我来说是一个很大的禁忌。优化查询本身并非易事:我明白你的意思了。考虑到实际意义重大的数字。但是,根据经验,索引永远不能替代糟糕的设计选择是的,我认为对一百万条记录进行5分钟的查询(我刚刚注意到)并没有那么糟糕。情况可能更糟
UPDATE users
   SET tweets =
        ( SELECT COUNT(1)
            FROM tweets
           WHERE tweets.from_user = users.screen_name
        )
 WHERE users.tweets = 0
 LIMIT 150
;