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_Performance - Fatal编程技术网

Php MySql:需要提高查询的性能

Php MySql:需要提高查询的性能,php,mysql,performance,Php,Mysql,Performance,我需要提高我的查询速度,因为它在一个大数据库上花费的时间太长了 我有下列表格 vb_user +++++++++++++++++++++++++++++++++ vb_post ++userid++username++posts++ +++++++++++++++++++++++++++++++++ vb_post ++++++++++++++++++++++++ vb_post ++用户标识++日期行++ ++++++++++++++++++++++++

我需要提高我的查询速度,因为它在一个大数据库上花费的时间太长了

我有下列表格

    vb_user
+++++++++++++++++++++++++++++++++

    vb_post
++userid++username++posts++

+++++++++++++++++++++++++++++++++

    vb_post
++++++++++++++++++++++++

    vb_post
++用户标识++日期行++

++++++++++++++++++++++++

    vb_post
我使用这个查询

SELECT VBU.userid AS USER_ID
, VBU.username AS USER_NAME
, COUNT(VBP.userid) AS NUMBER_OF_POSTS_FOR_30_DAYS
            , FROM_UNIXTIME(VBU.joindate) as JOIN_DATE
        FROM vb_user AS VBU
        LEFT JOIN vb_post AS VBP
        ON VBP.userid = VBU.userid
            WHERE VBU.joindate BETWEEN '__START_DATE__' AND '__END_DATE__' 
                AND VBP.dateline BETWEEN VBU.joindate AND DATE_ADD(FROM_UNIXTIME(VBU.joindate), INTERVAL 30 DAY)
            GROUP BY VBP.userid
            ORDER BY NUMBER_OF_POSTS_FOR_30_DAYS DESC"
我必须选择从加入时到加入后30天内发布最多的用户。。。。。如果没有FROM_UNIXTIME函数,我想不出怎么做

但这需要很多时间。您对如何提高查询性能有何想法

下面是explain的输出

id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,VBP,index,userid,threadid_visible_dateline,18,NULL,2968000,"Using where; Using index; Using temporary; Using filesort"
1,SIMPLE,VBU,eq_ref,PRIMARY,PRIMARY,4,vb_copilul.VBP.userid,1,"Using where"
这是关于桌子的信息

Table,"Create Table"
vb_user,"CREATE TABLE `vb_user` (
  `userid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(100) NOT NULL DEFAULT '',
  `posts` int(10) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`userid`),
  KEY `usergroupid` (`usergroupid`),
) ENGINE=MyISAM AUTO_INCREMENT=101076 DEFAULT CHARSET=latin1"

Table,"Create Table"
vb_post,"CREATE TABLE `vb_post` (
 `postid` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `threadid` int(10) unsigned NOT NULL DEFAULT '0',
 `parentid` int(10) unsigned NOT NULL DEFAULT '0',
 `username` varchar(100) NOT NULL DEFAULT '',
 `userid` int(10) unsigned NOT NULL DEFAULT '0',
 `title` varchar(250) NOT NULL DEFAULT '',
 `dateline` int(10) unsigned NOT NULL DEFAULT '0',
 `pagetext` mediumtext,
 `allowsmilie` smallint(6) NOT NULL DEFAULT '0',
 `showsignature` smallint(6) NOT NULL DEFAULT '0',
 `ipaddress` char(15) NOT NULL DEFAULT '',
 `iconid` smallint(5) unsigned NOT NULL DEFAULT '0',
 `visible` smallint(6) NOT NULL DEFAULT '0',
 `attach` smallint(5) unsigned NOT NULL DEFAULT '0',
 `infraction` smallint(5) unsigned NOT NULL DEFAULT '0',
 `reportthreadid` int(10) unsigned NOT NULL DEFAULT '0',
 PRIMARY KEY (`postid`),
 KEY `userid` (`userid`),
 KEY `threadid` (`threadid`,`userid`),
 KEY `threadid_visible_dateline` (`threadid`,`visible`,`dateline`,`userid`,`postid`),
 KEY `dateline` (`dateline`),
 KEY `ipaddress` (`ipaddress`)
) ENGINE=MyISAM AUTO_INCREMENT=3009320 DEFAULT CHARSET=latin1"

要改进查询,可以做两件事:

  • 不要将VBP.datetime转换为unix时间。直接使用日期之间的查询。在查询中,服务器必须转换数据库中的所有日期以进行比较,而不是使用本机类型。如果您总是使用datetime列作为unix时间戳,那么将其声明为Double(我想是吧?)而不是datetime(或者时间戳,不管您选择了什么)。这样,您也可以加快其他操作的速度
  • 向datetime列添加索引,以确保查询速度足够快

其他一切看起来都正常

您对查询做了解释吗?如果是这样的话,那会告诉你什么?很好解释。你能把完整的表格定义贴出来吗?最好是
SHOW CREATE TABLE vb_user
SHOW CREATE TABLE vb_post
的结果,甚至可能是一些以
插入到..
语句形式的示例数据。我刚刚看到了您添加的explain和CREATE TABLE语句-是的,日期行列已经是int类型了。查看Explain查询—它确实使用了一个相当复杂的键,但仍然扫描数千行。因此,请尝试删除强制转换,并尝试实际删除threadid\u visible\u dateline键-这可能会迫使它使用更好的键。它确实需要在dateline和userid上建立索引。当然,应该有一个索引,但在途中添加索引太多字段可能有害!因此,我的建议是先删除该索引,看看它是如何运行的。然后(你是对的)尝试在这两个字段上添加索引。我不知道MySQL在选择索引方面有多聪明,但我必须尝试一下,看看它是否更喜欢那个索引。MySQL不支持基于函数的索引。因此,正如Dimitar所说,不要将VBP.datetime转换为unix时间。它阻止数据库使用日期线索引。好的,删除时间戳转换效果很好。但是我现在对下面的查询有另一个问题。。。。我用新的查询更新了帖子