【问题标题】:Converting a php loop to a simple MySQL query将 php 循环转换为简单的 MySQL 查询
【发布时间】:2015-02-20 21:26:09
【问题描述】:

抱歉,这是一个愚蠢的问题。感谢您的宝贵时间。我四处搜索并找到了类似的问题/答案 - 但还没有找到我正在寻找的东西。

我习惯于通过 PHP 进行所有 MySQL 调用 - 但最近 - 我接到了一项任务,即处理一个包含 5000 000 个股票经纪人记录的非常大的数据库表。我拥有的 PHP 工作正常 - 但需要几个小时才能完成。认为使用简单的 MySQL 调用会快得多……“简单”的感觉让我迷失了。

我的表:

| ID | My_Stockbroker | My_Start_Date | My_End_Date | POST_SIZE |
| 1  |     DAVE       |  2000-06-19   | 2000-06-19  |     2     |
| 2  |     DAVE       |  1999-03-02   | 2002-09-06  |     0     |
| 3  |     DAVE       |  1999-03-14   | 2002-12-10  |     0     |
| 4  |     SAM        |  2000-06-19   | 2000-06-19  |           |

更新的目标表是My_Table - 我想更新所有POST_SIZE' values onMy_Table`


我的 PHP 非常简单:

  • POST_SIZE 最初为空白
  • 从 My_Table = "DAVE" 中获取一个 My_Stockbroker 名称
  • 计算 My_Table 中 = "DAVE" 并且在特定日期范围内的任何其他记录(不包括正在处理的记录) IE。 My_Table.My_Start_Date My_Table.My_Start_Date && My_Table.My_End_Date > "ID1".My_Table.My_Start_DatePOST_SIZE ++;

我的PHP代码是这样的:

// Get 1 record
$sql = "SELECT `ID`, ` My_Stockbroker`,  `My_Start_Date`, from `".$Table."` WHERE ` My_Stockbroker` != '' AND `POST_SIZE` = '' LIMIT 1"; //

while($row = $result->fetch_assoc()){// while 1 record result
    $ My_Stockbroker_To_Examin_ID = $row["ID"];
    $ My_Stockbroker_To_Examin = $row[" My_Stockbroker"];
    $ My_Stockbroker_To_Examin_My_Start_Date = $row["My_Start_Date"];
}

/////// GET ALL RECORDS FOR SPECIFIC  My_Stockbroker that fall within specific date ///////
$sql = "SELECT `ID` FROM `".$Table."` WHERE `My_Start_Date` < 
'".$My_Stockbroker_To_Examin_My_Start_Date."' AND `My_End_Date` > 
'".$My_Stockbroker_To_Examin_My_Start_Date."' AND `My_Stockbroker` = 
'".$My_Stockbroker_To_Examin."' AND `ID` != '".$ My_Stockbroker_To_Examin_ID ."'"; // 

if($result = $conn->query($sql)){//
   $POST_SIZE = $result->num_rows;
}

// now write back the number of rows found    
$sql = "UPDATE `".$Table."` SET `POST_SIZE` = '".$POST_SIZE."', WHERE `ID` = '".$My_Stockbroker_To_Examin_ID."'; ";

正如我所说 - 我拥有的 PHP 代码完美无缺。 我只是没有时间等待它完成。

如何在一张表上仅使用 MySQL 来实现这一点?

读取一条记录/计算日期范围内的所有记录/将值写入POST_SIZE

我是否需要即时创建一堆临时表并加入等? 或者这可以在 MySQL 循环中实现吗? MySQL通常单独更快吗? - 还是我的 PHP 出了问题?

【问题讨论】:

  • 你的表被索引了吗?
  • 是的!非常感谢。
  • 我正在寻找一个完整的语句,它写回每一行的POST_SIZE 列。
  • 您在为每个股票经纪人单独查询什么?这确实是很多查询,可能会产生很大的影响。
  • 还有一个原因是你不能只减去 1 而不是拥有整个 NOT 子句吗?

标签: php mysql loops


【解决方案1】:

您可以在单个查询语句中完成整个过程,例如

SELECT `ID` 
FROM 
(
SELECT `ID` as MSID, 
`My_Stockbroker` as MSB,  
`My_Start_Date` as MSD
 from My_Table
 WHERE `My_Stockbroker` IS NOT NULL AND `POST_SIZE` IS NULL
 ORDER BY `ID` LIMIT 1
) tab
WHERE `My_Start_Date` < MSD
AND `My_End_Date` > MSD 
AND `My_Stockbroker` = MSB
AND `ID` != MSID;

【讨论】:

  • 谢谢拉胡尔。这会写回同一张表吗?
  • @Kreeverp,不,这是一个选择语句。如果您打算 UPDATE 在您的帖子中..您可以将选择查询的结果包含到您的 UPDATE 语句中..
  • 我在寻找一个也写回结果的声明?
  • 首先获取所有数据(一次传递,而不是为每个代理单独传递),然后进行一次更新。
【解决方案2】:

这个sql我没试过,不过应该是这样的

UPDATE My_Table set Post_size = (SELECT COUNT(ID) FROM My_Table 
 WHERE ID <> My_Stockbroker_To_Examin_ID 
 AND My_Start_Date < My_Stockbroker_To_Examin_My_Start_Date 
 AND My_End_Date > My_Stockbroker_To_Examin_My_Start_Date 
 AND My_Stockbroker = My_Stockbroker_To_Examin)

您可以将这些变量替换为所需的值。

【讨论】:

  • 谢谢 Neels - 我会试一试
  • 你知道吗?...这通常应该使用 MySQL 更快 - 或者我的 PHP 可能会出错?
  • 快速取决于许多其他标准。为此,我需要您的表格结构和其他东西!我们将不得不查看正确的列是否被索引。
  • 谢谢尼尔斯。我想我只是在询问 - 在最佳设置下 - 对于 PHP 和 MySQL。用 PHP 处理 5000 000 条记录需要几个小时是否合理?使用 MySQL 应该会快很多吗?使用大型数据库进行此类处理的标准时间长度是多少?我想我问是因为我以前没有使用过非常大的数据库表。所以我不确定会发生什么。
猜你喜欢
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
  • 2014-06-18
  • 2016-08-10
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多