PHP PDO SQL - 更新内部联接查询在执行期间冻结

时间:2016-01-13 17:24:58

标签: php mysql mysqli pdo

我需要运行每日PHP脚本,下载数据文件并按顺序执行一堆SQL查询以导入和优化数据。

我在PHP中执行我的一个查询时遇到问题,似乎冻结了我服务器上的mysqld进程。奇怪的是,从Sequel Pro数据库客户端程序(Mac)运行时,运行相同的查询并不会出现类似的问题。

查询在超过一百万行的大型表上运行更新。这是我使用的存储过程:

DELIMITER ;;
CREATE PROCEDURE spSetTripIdInStopTimes()
BEGIN 

-- SET META_TRIP_ID IN IMPORT_STOP_TIMES    
UPDATE import_stop_times 
INNER JOIN ref_trips ON 
(
    import_stop_times.trip_id = ref_trips.trip_id 
    AND import_stop_times.meta_agency_id =ref_trips.meta_agency_id
) 
 SET import_stop_times.meta_trip_id = ref_trips.meta_trip_id;

END;;
DELIMITER ; 

使用

调用该过程时
CALL spSetTripIdInStopTimes; 
在Sequel Pro中,结果是1241483行受影响,所用时间约为90秒。

使用PHP PDO,我使用

运行相同的命令
$result = $database->runExecQuery("CALL spSetTripIdInStopTimes");

然而,它在这个查询中停留超过24小时仍然没有完成。当我取消PHP脚本时,我可以看到mysqld进程仍在使用%99.5 CPU。此时,我使用&sudo service mysql restart'重新启动SQL。

我也尝试过使用PHP的mysqli,但这种方法也会发生冻结。

$mysqli->query("CALL spSetTripIdInStopTimes")

是否有人能够解释为什么会发生这种情况或提出另一种方法?

提前谢谢。

注意:我也尝试在PHP上使用较旧的mysql,但我使用的版本(5.5.9-1ubuntu4.14)告诉我该命令已被弃用并停止脚本。

[UPDATE]

我还尝试直接在命令行上运行存储过程:

mysql --user=[username] --password=[password] --execute="call spSetTripIdInStopTimes()" [tablename]

哪个有效。

所以我尝试用PHP exec() function运行相同的命令:

exec("mysql --user=[username] --password=[password] --execute=\"call spSetTripIdInStopTimes()\" [table name]");

不幸的是,它仍然悬而未决。我开始怀疑这是否是由于PHP的限制或开销。

[更新2] 这是我使用的PHP PDO连接选项数组:

array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
// Allow file reading, need following settings to import data from txt files
PDO::MYSQL_ATTR_LOCAL_INFILE => true,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
PDO::ATTR_EMULATE_PREPARES => true)

[更新3]

我使用自定义数据库对象,因此我将显示$ database-> runExecQuery()的函数以澄清:

  function runExecQuery($queryString)
    {
        $db = $this-> getConnection(); // Connect to database

        try{
            return array(
                "success"=> true,
                "data"=>$db->exec($queryString)
            );
        }
        catch (PDOException $ex)
        {
            return array(
                "success"=> false,
                "errMessage"=> "ERROR[{$ex->getCode()}]".($this-> Debug ? "{$ex}" : "")
            );
        }
    }

变量$ db是初始化的连接变量,如下所示:

// Create address string
$db_address = 
            "mysql:host={$settings['db_hostname']};".
            "dbname={$settings['db_name']};".
            "charset={$settings['db_charset']}";    
// Create connection to database
$db = new PDO($db_address, $settings['db_user'], $settings['db_pw'], $options);

其中$ options是[Update 2]中的数组。

[更新4]

Mihai关于改变PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false的建议有一些有希望的结果,因为查询似乎已经完成。但是,经过更多的测试后,我发现PHP脚本有时会在查询运行时占用50%的时间。即使在SQL表中使用相同的数据集也是如此。

0 个答案:

没有答案