Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/251.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 连接查询在真实数据库上太慢,在小数据库上运行良好_Php_Mysql_Database_Performance_Join - Fatal编程技术网

Php 连接查询在真实数据库上太慢,在小数据库上运行良好

Php 连接查询在真实数据库上太慢,在小数据库上运行良好,php,mysql,database,performance,join,Php,Mysql,Database,Performance,Join,我需要这个mysql查询的帮助,它执行的时间太长或者根本不执行 (我试图做的是更复杂问题的一部分,我想创建一个PHP cron脚本,它将执行一些繁重的查询,并根据返回的结果计算数据,然后使用这些数据将其存储在数据库中,以便进一步更方便地使用。我很可能会在这里提出有关该过程的问题。) 首先,让我们尝试解决这些繁重查询的一个问题 事情是这样的: 我有表:用户\u bonitet。此表包含以下字段:id、用户id、bonitet、tstamp 第一个重要提示:当我说用户时,请理解用户实际上是公司,而不

我需要这个mysql查询的帮助,它执行的时间太长或者根本不执行

(我试图做的是更复杂问题的一部分,我想创建一个PHP cron脚本,它将执行一些繁重的查询,并根据返回的结果计算数据,然后使用这些数据将其存储在数据库中,以便进一步更方便地使用。我很可能会在这里提出有关该过程的问题。)

首先,让我们尝试解决这些繁重查询的一个问题

事情是这样的:

我有表:用户\u bonitet。此表包含以下字段:id用户idbonitettstamp

第一个重要提示:当我说用户时,请理解用户实际上是公司,而不是人。所以user.id是某个公司的id,但由于一些其他原因,我在这里使用的表被称为“users

users\u-bonitet表中的三个关键字段是:user\u-id(参考user.id)、bonitet(表示用户的强度,它可以有3个值,1-2-3,其中3是最好的)和tstamp(存储插入bonitet的时间。每当某个用户的bonitet值发生更改时,插入新行时会使用该插入的tstamp,当然还有新的bonitet值。)。因此,基本上,一些用户可以将bonitet设置为1,表示其处境不好,但经过一段时间后,它可以更改为3,表示他做得很好,并且更改的时间存储在tstamp

现在,我将列出我们需要在查询中使用的其他表,然后我将解释原因。这些表包括:用户俱乐部俱乐部提供俱乐部地区

一些用户(公司)是俱乐部的成员。俱乐部的成员可以获得一些俱乐部的优惠(他向人们和其他俱乐部成员代表他的产品),并且他在一些地区开展业务

我需要做的是为每个俱乐部提供的服务获取bonitet价值(由某个俱乐部成员用户提供)但仅适用于id为1100000的特定区域;由于每个用户的bonitet值随时间而变化,这意味着我只需要获取最新的值。因此,如果某些用户在2012年1月21日的bonitet值为1,但后来在2012年5月26日的bonitet值变为2,我只需要获取2,因为这是当前值

我用我现在使用的示例数据库模式和查询做了一个SQL处理。在这个小数据库上,查询工作符合我的要求,速度很快,但在实际数据库上非常慢,有时根本不执行

请看这里:

我的问题是:我是否使用了错误的查询来获取所有这些数据?我得到了正确的结果,但可能我的查询不好,这就是为什么它执行得如此慢的原因?我如何提高它的速度?我曾尝试使用phpmyadmin放置索引,但没有多大帮助

我的问题是:

SELECT users_bonitet.user_id, users_bonitet.bonitet, users_bonitet.tstamp,
       club_offer.id AS offerId, club_offer.rank

FROM users_bonitet

INNER JOIN (
     SELECT max( tstamp ) AS lastDate, user_id
     FROM users_bonitet
     GROUP BY user_id
)lastDate ON users_bonitet.tstamp = lastDate.lastDate

AND users_bonitet.user_id = lastDate.user_id

JOIN users ON users_bonitet.user_id = users.id
JOIN club ON users.id = club.user_id
JOIN club_offer ON club.id = club_offer.club_id
JOIN club_territories ON club.id = club_territories.club_id

WHERE club_territories.territory_id = 1100000

因此,我选择bonitet值作为所有俱乐部提供的服务,这些用户是俱乐部的成员,在id为1100000的区域内运营。重要的是,我选择club_offer.id作为offerId,因为我需要在我的应用程序代码中使用该offerId,以便我可以根据每个提供返回的bonitet值进行一些计算d在字段“club_offer.rank”中插入计算出的数据,每行的id为offerId。

您的查询看起来不错。如果您添加一个复合索引来帮助子查询为每个用户从
用户\u botinet
中查找最新条目,我怀疑您的查询性能可能会有所提高

子查询是:

   SELECT max( tstamp ) AS lastDate, user_id
     FROM users_bonitet
    GROUP BY user_id
如果将
(user\u id,tstamp)
作为索引添加到此表中,则该子查询可以满足非常高效的查询

请注意,如果此
users\u botinet
表中有一个自动递增的id号,则可以重构子查询以使用该id号,而不是
tstamp
。这将消除重复的可能性,而且效率更高,因为有一个唯一的id用于加入。就像这样

  FROM users_botinet
  INNER JOIN (
         SELECT MAX(id) AS id
           FROM users_botinet
          GROUP BY user_id
       ) ubmax ON users_botinet.id = ubmax.id
在这种情况下,复合索引将是
(用户id,id


专业提示:除非你知道你需要索引,否则不要添加太多索引。阅读索引如何帮助你是一个好主意。例如。

你能用sql处理示例数据吗?请阅读我的帖子,链接就在那里。如果你在SELECT语句中使用lastDate.lastDate而不是用户,会发生什么?谢谢你提供的关于usin的提示子查询中的g id。但是使用maxfinder索引会使查询速度减慢3倍。奇怪;
maxfinder
看起来不错。请提供
EXPLAIN SELECT…
带和不带
maxfinder
(您可以保留索引,但在两个位置使用
忽略索引(maxfinder)
)还可以使用SQL\u NO\u缓存来确保查询缓存正在延迟计时。
  FROM users_botinet
  INNER JOIN (
         SELECT MAX(id) AS id
           FROM users_botinet
          GROUP BY user_id
       ) ubmax ON users_botinet.id = ubmax.id