Yii框架 - InnoDB vs MyISAM

7
我有一个问题:我使用Yii和InnoDB构建了一个大型应用程序,但插入/更新需要非常非常长的时间。以下是我的php报告:
INNODB: admin用户更新需时55.247464895248秒 ekuskov用户更新需时13.282548904419秒 doriwall用户更新需时0.002094030380249秒
MYISAM: admin用户更新需时7.8317859172821秒 ekuskov用户更新需时1.6304929256439秒 doriwall用户更新需时0.0020859241485596秒
有人能提供一些加速插入/更新的解决方案吗?
编辑----------------------------------------------
现在我使用了一些非常简单的插入循环:
public function run($args) {
    $time = -microtime(true);

    $begin    = DateTime::createFromFormat('Y-m-d H:i:s', '2010-01-01 00:00:00');
    $end    = DateTime::createFromFormat('Y-m-d H:i:s', '2013-01-01 00:00:00');
    $end->add(new DateInterval('P1D'));
    $interval = DateInterval::createFromDateString('1 day');
    $days     = new DatePeriod($begin, $interval, $end);


    foreach ( $days as $day ) {
        echo "i";
        $track = new TimeTracking();
        $track->user_id = 25;
        $track->date = $day->format('Y-m-d H:i:s');
        $track->active = 4;
        $track->save(false);
    }

    $time += microtime(true);
    echo count($days)." items insert - $time seconds\n";
}

现在,插入时间如下:

InnoDB:项目插入-72.269570827484秒

MyISAM:项目插入-0.87537479400635秒

[编辑] 现在我计算整个保存方法和Yii模型的“save()”函数所需的时间:

更新:model->save(false)-0.1096498966217秒

更新:控制器保存函数()-0.1302649974823秒

创建:model->save(false)-0.052282094955444秒

创建:控制器保存函数()-0.057214975357056秒

为什么只有save()方法需要这么长时间?

[编辑] 我已经测试了save()与command(),它们持续的时间相同:

$track->save(false);

或者

$command = Yii::app()->db->createCommand();
            $command->insert('timeTracking', array(
                    'id'=>NULL,
                    'date'=>$track->date,
                    'active'=>$track->active,
                    'user_id'=>$track->user_id,
            ));

编辑 -----------------------------

下面是插入1,097个对象的统计数据:

save(): 0.86-0.94, 
$command->insert(): 0.67-0.72,
$command->execute(): 0.46-0.48,
mysql_query(): 0.33-0.36

最终答案:如果您想使用大量的INSERT或UPDATE方法,您应该考虑创建直接MYSQL调用的函数,这样您将节省近70%的执行时间。

祝好,

Edgar


该函数仅更新每个用户的余额次数。 - ekussberg
查询:将数据插入timeTracking表中,字段为(id, date, active, user_id),值分别为 (NULL, $track->date, $track->active, $track->user_id)。注:底部我写了该命令的确切指令。 - ekussberg
7
请记住,InnoDB引擎符合ACID标准。如果您要向InnoDB数据库插入/更新大量数据,那么它必须将每个修改都写入磁盘以保证数据安全。尝试将这些多次保存的操作包装到一个事务中,以便InnoDB可以将这些磁盘写入组合为一个修改,并在事务结束时执行。 - biziclop
可能是[为什么MySQL InnoDB插入如此缓慢?]的重复问题(链接:https://dev59.com/_Wkw5IYBdhLWcg3wi7Fz)。 - Maxim Krizhanovsky
此外:如果您追求原始速度,那么您不想使用ActiveRecord而是DAO/PDO => 内存占用更少且更快,因为您可以摆脱所有不必要的验证等。 - Haensel
显示剩余6条评论
6个回答

1

如果插入和更新时表格出现爬行现象,可能意味着您过于依赖索引。请记住,每次提交后,数据库都必须停止并重新编译索引。


0

使用Yii和InnoDB时,您应该将命令包装在事务中,如下所示:

$transaction = Yii::app()->db->beginTransaction();

try {
    // TODO Loop through all of your inserts

    $transaction->commit();
} catch (Exception $ex) {
    // There was some type of error. Rollback the last transaction
    $transaction->rollback();
}

0
解决方案是:对于那些需要大量插入和快速响应的表格,将它们转换为MyISAM。否则用户必须等待很长时间,而且有一种威胁,即PHP Max Script Execution Time会停止您的脚本。

0

InnoDB在许多方面比MyISAM更复杂、功能更丰富。这使得它变慢,你在查询、配置或其他方面几乎无法解决这个问题。然而,MySQL正在努力通过最近的更新来缩小差距。

看看版本5.6:

http://dev.mysql.com/doc/refman/5.6/en/innodb-performance.html

如果你的MySQL版本过低,最好的选择可能是升级。


0
根据MySQL专家的建议,在明确证明需要MyISAM之前,请使用InnoDB。性能问题不是一个好的论据。
如果您有大型应用程序,您可能会面临表级锁定和数据不一致的问题。因此,请使用InnoDB。
您的性能问题可能与缺乏索引或硬盘及其文件系统问题有关。
我曾经处理过具有数亿行的表格,这些表格不断地从多个连接进行更新和插入。这些表格使用了InnoDB引擎。
当然,如果您有需要一次添加大量数据的情况,请使用一个插入语句来添加它们。

0

InnoDB提供了创建关系和约束的选项,这使得数据库更快,并且您将能够使用这些关系生成模型和crud。

您还可以考虑将查询拆分为较小的查询,并逐个执行它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接