0

只是想看看你们对这次表演的看法......

我有一个 Intel i7 ivybridge quad、16GB DDR3 RAM、7200RPM 驱动器用于服务器/mysql 驱动器等...

我对 1000 条记录进行了简单更新: $q2 = "UPDATE msg_inbox SET receivedtime='$epochTime' WHERE id='$id' LIMIT 1 ";

授予每一个都是基于当前的 foreach 循环(在每个返回的 id 上)触发的。但是如果我注释掉这个更新查询,页面需要 0.0300 秒来加载所有 1000 条记录。

但是使用更新查询,它会在页面完全完成之前滞后 57 秒...我使用 PHP microtime 进行了检查。

这是正常的和预期的性能还是这里有什么问题?(也许是我的机器)

问候

表格信息: 定义:

CREATE TABLE `msg_inbox` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `sender` varchar(20) NOT NULL,
  `sender_name` varchar(100) NOT NULL,
  `receiver` varchar(20) NOT NULL,
  `receiver_name` varchar(20) NOT NULL,
  `msg` tinytext NOT NULL,
  `senttime` int(10) NOT NULL,
  `receivedtime` int(10) NOT NULL,
  `operator` varchar(20) NOT NULL,
  `device_name` varchar(50) NOT NULL,
  `msgtype` varchar(20) NOT NULL,
  `read_by` varchar(20) NOT NULL COMMENT 'marks a message to be read or unread with ID of who read it',
  `folder_id` int(11) DEFAULT '0',
  `owner` int(11) DEFAULT '0',
  `prefix` varchar(10) NOT NULL,
  `raw_gwdata` text,
  `stat` enum('normal','important','deleted') NOT NULL DEFAULT 'normal',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8528 DEFAULT CHARSET=latin1;

目前表中共有 7887 行..

4

2 回答 2

1

猜测 id 列已编入索引...我会说您需要查看 MySql 连接限制,HERE

我会说你的机器和查询很好,你需要仔细看看你的 mysql / php 配置。

PS:我见过 4 gig ram 的双核在 30 秒内完成 1000 次插入。

于 2013-05-09T10:32:13.280 回答
0

加快速度的可能解决方案是批量更新。Id 是唯一的,如果您只想更新现有的 id(而不是尝试更新不存在的 id),那么您可以使用 INSERT.....ON DUPLICATE KEY UPDATE 类型查询。

这样做的好处是您可以在单个语句中使用新值更新数百行,而且速度非常快。

这样做时,我有时会使用一个类来跟踪记录,它可以确定何时进行插入。

下面是一个示例(使用 php)(未直接测试,因此可能是奇怪的错字):-

<?php

$InsertObject = new generic_insert($db_object, 'msg_inbox', array('id', 'receivedtime'), 1000);

foreach ($DetailsArray AS $DetailItem)
{
    InsertObject->InsertItem("($DetailItem[id], $DetailItem[receivedtime])");
}

unset($InsertObject);

class generic_insert
{
    var $db;
    var $InsertArray = array();
    var $TableName = '';
    var $InsertBatchSize = 1000;
    var $UpdateClause = '';
    function __CONSTRUCT($db, $TableName, $ColumnArray, $InsertBatchSize = 1000)
    {
        $this->db = $db;
        $this->TableName = $TableName;
        $this->ColumnArray = $ColumnArray;
        $this->InsertBatchSize = $InsertBatchSize;

        foreach (array_slice($this->ColumnArray, 1) AS $ColumnItem)
        {
            $UpdateArray = "$ColumnItem=VALUES($ColumnItem)";
        }
        if (count($UpdateArray) > 0)
        {
            $this->UpdateClause = " ON DUPLICATE KEY UPDATE SET ".implode(',', $UpdateArray);
        }
    }
    function __DESTRUCT()
    {
        if (count($this->InsertArray) > 0)
        {
            $this->PerformInsert();
        }
    }

    public function InsertItem($InItem)
    {
        $this->InsertArray[] = $InItem;
        if (count($this->InsertArray) > $this->InsertBatchSize)
        {
            $this->PerformInsert();
        }
    }

    private function PerformInsert()
    {
        $query = "INSERT INTO ".$this->TableName." (`".implode('`, `', $this->ColumnArray)."`) VALUES ".implode(",", $this->InsertArray)." ".$this->UpdateClause;
        $stmtId = $this->db->query($query);
        if ($stmtId === false)
        {
            die("Insert To ".$this->TableName." Failed - ".$this->db->error());
        }
        else
        {
            $this->db->free_result($stmtId);
        }
        $this->InsertArray = array();
    }
}

?>

该类接受一些参数,包括数据库对象、表名、列名数组(假设第一个是主键)和一次完成的最大更新数(在本例中为 1000)。它应该是相当通用的。

于 2013-05-10T14:26:30.420 回答