8

私はphpでWebServiceを作成しています。これは、私のWebサイトがAjax呼び出しで情報を照会するために使用します。

最初は、組み込みのphp mysql libを使用して標準的な方法で実行し、すべてのクエリを手動で記述し、MySQLWorkbenchなどでデータモデル全体を作成しました。これは非常に時間がかかり、後でデータモデルを変更しなければならない場合、すべてが非常に複雑になり始めるので、 PHP ORMを探すことにしました。そして、純粋な魔法と喜びのように見えるRedBeanを見つけました。

私がパフォーマンスの問題に非常に苦労していることを除いて。私のサイトは、ユーザーが自分のテレビシリーズのリストを作成するためのサイトです。私は一連の外部ソースを照会し、まだデータベースにない場合はデータベースに挿入します。そうでない場合は、自分のデータベースofcから取得します。

この外部ソースから取得したxmlには、シリーズ、シーズン、エピソードなどがリストされており、すべてこのように保存されます。

function InsertSerie($serie) {
    $serieBean = $this->CreateSerieBean($serie->Series);
    $genreBeans = $this->CreateGenreBeans($serie->Series->Genre);
    $actorBeans = $this->CreateActorBeans($serie->Series->Actors);
    $episodeBeans = array();
    foreach ($serie->Episode as $episode) {
        $episodeBean = $this->CreateEpisodeBean($episode);
        $seasonBean = $this->CreateSeasonBean($episode);
        $writerBeans = $this->CreateWriterBeans($episode->Writer);
        $guestBeans = $this->CreateActorBeans($episode->GuestStars);
        $directorBeans = $this->CreateDirectorBeans($episode->Director);
        R::associate($episodeBean, $seasonBean);
        foreach ($writerBeans as $bean) {
            R::associate($episodeBean, $bean);
        }
        foreach ($guestBeans as $bean) {
            R::associate($episodeBean, $bean);
        }
        foreach ($directorBeans as $bean) {
            R::associate($episodeBean, $bean);
        }
        $episodeBeans[] = $episodeBean;
    }
    foreach ($genreBeans as $bean) {
        R::associate($serieBean, $bean);
    }
    foreach ($actorBeans as $bean) {
        R::associate($serieBean, $bean);
    }
    foreach ($episodeBeans as $bean) {
        R::associate($serieBean, $bean);
    }
}

function CreateGenreBeans($genres) {
    if(empty($genres)) { return; }
    $genre = explode("|", $genres);
$genreBeans = array();
foreach ($genre as $g) {
    if($g != '') {
            $genreBeans[] = $this->CreateGenreBean($g);
        }
    }
    return $genreBeans;
}

function CreateGenreBean($genre) {
    $bean = R::dispense('genre');
    $bean->name = (string)$genre;
    return $bean;
}

function CreateDirectorBeans($directors) {
    if(empty($directors)) { return; }
    $director = explode("|", $directors);
$directorBeans = array();
foreach ($director as $d) {
    if($d != '') {
            $directorBeans[] = $this->CreateDirectorBean($d);
        }
    }
    return $directorBeans;
}

function CreateDirectorBean($director) {
    $bean = R::dispense('director');
    $bean->name = (string)$director;
    return $bean;
}

function CreateActorBeans($actors) {
    if(empty($actors)) { return; }
    $actor = explode("|", $actors);
$actorBeans = array();
foreach ($actor as $a) {
    if($a != '') {
            $actorBeans[] = $this->CreateActorBean($a);
        }
    }
    return $actorBeans;
}

function CreateActorBean($actor) {
    $bean = R::dispense('actor');
    $bean->name = (string)$actor;
    return $bean;
}

function CreateWriterBeans($writers) {
    if(empty($writers)) { return; }
    $writer = explode("|", $writers);
$writerBeans = array();
foreach ($writer as $w) {
    if($w != '') {
            $writerBeans[] = $this->CreateWriterBean($w);
        }
    }
    return $writerBeans;
}

function CreateWriterBean($writer) {
    $bean = R::dispense('writer');
    $bean->name = (string)$writer;
    return $bean;
}

function CreateSerieBean($serie) {  
    $bean = R::dispense('serie');
    $bean->serie_id = (string)$serie->id;
    $bean->airs_day_of_week = (string)$serie->Airs_DayOfWeek;
    $bean->airs_time = (string)$serie->Airs_Time;
    $bean->content_rating = (string)$serie->ContentRating;
    $bean->first_aired = (string)$serie->FirstAired;
    $bean->imdb_id = (string)$serie->IMDB_ID;
    $bean->language = (string)$serie->Language;
    $bean->network = (string)$serie->Network;
    $bean->overview = (string)$serie->Overview;
    $bean->rating = (string)$serie->Rating;
    $bean->rating_count = (string)$serie->RatingCount;
    $bean->run_time = (string)$serie->Runtime;
    $bean->serie_name = (string)$serie->SeriesName;
    $bean->status = (string)$serie->Status;
    $bean->last_updated = (string)$serie->lastupdated;
    $bean->thumbnail = (string)$serie->thumbnail;
    return $bean;
}

function CreateSeasonBean($episode) {
    $bean = R::dispense('season');
    $bean->season_id = (string)$episode->seasonid;
    $bean->season_number = (string)$episode->SeasonNumber;
    return $bean;
}

function CreateEpisodeBean($episode) {
    $bean = R::dispense('episode');
    $bean->episode_id = (string)$episode->id;
    $bean->episode_name = (string)$episode->EpisodeName;
    $bean->episode_number = (string)$episode->EpisodeNumber;
    $bean->first_aired = (string)$episode->FirstAired;
    $bean->imdb_id = (string)$episode->IMDB_ID;
    $bean->language = (string)$episode->Language;
    $bean->overview = (string)$episode->Overview;
    $bean->rating = (string)$episode->Rating;
    $bean->rating_count = (string)$episode->RatingCount;
    $bean->last_updated = (string)$episode->lastupdated;
    return $bean;
}

問題は、1つのシリーズを挿入するのに約5分かかり、重複も挿入することです。これを行っR::freeze();てもパフォーマンスは向上しません。

Q:この問題を修正するにはどうすればよいですか、redbeanのパフォーマンスを向上させるために何ができますか、それをより良く機能させるために自分のコードで何ができますか、または単に別のソリューション/アプローチフレームワークを使用する必要がありますか?

提案されたような共有リストを試しましたが、同じ結果になりました。

function InsertSerie($serie) {
    $serieBean = $this->CreateSerieBean($serie->Series);
    ...
    foreach ($serie->Episode as $episode) {
        $episodeBean = $this->CreateEpisodeBean($serieBean ,$episode);
        ...
        $this->CreateDirectorBeans($serieBean, $episode->Director);
        $serieBean->sharedEpisode[] = $episodeBean;
    }
    R::store($serieBean);
}

function CreateDirectorBeans($bean, $directors) {
    if(empty($directors)) { return; }
    $director = explode("|", $directors);
    foreach ($director as $d) {
        if($d != '') {
            $bean->sharedDirector[] = $this->CreateDirectorBean($d);
        }
    }
}

function CreateDirectorBean($director) {
    $bean = R::dispense('director');
    $bean->name = (string)$director;
    return $bean;
}
    ....
4

2 に答える 2

7

実行時間を 5 分から約 11 秒に短縮する方法を最終的に見つけましたが、それでもかなりの時間がかかりますが、データの量と実行しなければならない作業を考慮すると、そのハードウェアには適していると思います。

これらのコード行を追加しました

R::Begin();
R::associate($bean1, $bean2);
...
R::commit();

現在は、すべての作業を収集し、作業単位パターンのように 1 つの大きなトランザクションで実行します。また、重複の挿入を防ぐために、使用に切り替えました

$bean = R::findOrDispense($type, $sql, $values);

次に、Bean が既に存在する場合はそれを返します。そうでない場合は、新しいものを作成して返します。

于 2012-05-24T22:15:12.543 に答える
0

リレーションをループする代わりに、共有リストを使用してみましたか?

$serieBean->sharedActor[] = $actorBeans;
$serieBean->sharedEpisode[] = $episodeBeans;

http://www.redbeanphp.com/manual/shared_lists

于 2012-05-20T17:58:00.217 に答える