大Json数据到mysql

时间:2012-03-07 11:52:40

标签: php mysql json

我试图将json数据导入mysql.My json文件接近3.7Mb并且有近17k行(测试数据真实数据将近65k行)。但是我的脚本速度非常慢,需要将近8-9分钟。有什么快速的方法可以使用php进程界面将json数据导入mysql吗? 我现在试图添加进度条功能及其功能。

$veri=json_decode(file_get_contents('auctions.json'));

            $sayi=count($veri->alliance->auctions);
            $a=$veri->alliance->auctions;
            $yuzde=round($sayi/100);
            echo "<div id='tasiyici'>";
            $sql=$db->prepare("INSERT INTO auctions (id, auc, item, owner, bid, buyout, quantity, timeLeft) VALUES ('',?,?,?,?,?,?,?)");
            for ($i=0;$i<=$sayi;$i++){
                $sql->execute(array($a[$i]->auc,$a[$i]->item,$a[$i]->owner,$a[$i]->bid,$a[$i]->buyout,$a[$i]->quantity,$a[$i]->timeLeft));
                if($i%$yuzde=='0'){
                    $y=$i/$yuzde;

                    if(($y*4+4)>"180"){$pos=40-(($y*4+4)-180); $color="color:#fff";}
                    if(($y*4+4)>=220){$pos=0;}
                    echo "<div class='rakam' style='background-position:-".$pos."px 0;".$color."'>%".($y+1)."</div>";
                    echo "<div class='yuzde' style='width:".($y*4+4)."px;'></div>";
                    ob_flush();
                    flush();

                }


            }
            echo "</div>";

            echo "<br> $sayi data added.";

CSS代码

<style>
        body {
            font-family:Arial;
        }
            #tasiyici {
                width:400px;
                height:17px;
                display: block;
                position: relative;
                margin:50px auto;
                background:#e3e3e3;
                border-radius:5px;
                overflow: hidden;
                border:1px solid #ccc;
            }
            .yuzde {
                height:17px;
                display: block;
                width:1px;
                background:url("progressOverlay.png");
                position: absolute;
                top:0;
                left:0;
                z-index:1;
            }
            .rakam {
                width:40px;
                height:16px;
                display: block;
                line-height:17px;
                position: absolute;
                left:50%;
                top:0;
                margin-left:-20px;
                z-index:9999;
                background:url("progressOverlay.png") -40px 0 #e3e3e3 no-repeat;
                font-size:11px;
            }

        </style>

3 个答案:

答案 0 :(得分:1)

9分* 60秒= 540秒

17000/540 =插入时每秒约30.5条记录

因为你没有发布你的服务器配置,加载,ram等,所以我们不能直接把问题放在某一点上。无论如何30.5插入/秒对于严肃的服务器来说并不多。这当然非常可行,因为你的行大小似乎不大。

您需要做的是做一些严肃的测量。例如,缺少内存大小会产生问题。桌面上还有许多昂贵的索引会使插入变得非常困难。

如果你多次这样做(例如通过用户上传),为它创建一个队列可能是明智的,因为它总是需要一些时间。虽然17k插入应该可以在几秒钟内完成,而不是几分钟。

有很多关于优化MySQL插入的文档,这是对速度影响的一般概述:http://dev.mysql.com/doc/refman/5.0/en/insert-speed.html

乍一看它似乎不是你的剧本,这并不是特别的。虽然我会用2个脚本分开这个过程:

  1. 处理在后台运行的进程中的插入,如cron,常量运行脚本等。因此,上传数据,存储它,后台进程将处理该数据。也许为它创建一个表importjobs。
  2. 每个x记录你都可以这样做:

    UPDATE importjobs SET counter = :amountimported WHERE id=:jobid
    
    1. 一个脚本,让您回答状态。通过获取后台脚本写入的状态消息。

      SELECT counter / total AS partdone,counter,total FROM importjobs WHERE id =:jobid

    2. 通过这种方式,您可以完全独立于用户界面来衡量和改进流程。关注的分离发生了。您可以全速进行导入,并且可以完全从过程中分离更新指示器。

      根据您获得的速度,您可以决定是否要每5,10,20,60秒更新一次。这种查找非常便宜,所以你可以做很多次。主要是因为importjobs表也很小。

答案 1 :(得分:1)

我有一个类似的问题要解决,但我不知道外部API的记录数量。我意识到我的工作可能会在中期过程中失败而且我不想再重新开始。

令我感到震惊的是,你的问题在这方面是类似的。您要求数据库执行的操作是尝试插入记录,即使记录已存在也是如此。这很昂贵。

我所做的是构建一个存储数据密钥或一些唯一标识符的控制表。在处理期间,作业读取控制数据库以确定记录是否存在,如果存在,则跳到下一个记录,否则插入它。

我创建了一个记录编号限制器,我可以测试负载(比如限制前100条记录),使用这个工具,我能够在浏览器的5个打开标签中运行php脚本,以有效地创建并行加载。

答案 2 :(得分:0)

如果扩展插入仍然不够快,请尝试使用load data infile。它不会给你进步,但它会以我所知的最快的速度加载你的数据。

编辑这是mysql手册页http://dev.mysql.com/doc/refman/5.1/en/load-data.html的链接