0

あるテーブルから情報を取得し、別のテーブルのエントリを作成する必要があるかどうかを判断し (重複を回避)、その情報をページ テーブルに挿入するスクリプトがあります。問題は、現在コーディングされている方法で約 10,000 エントリのクエリを実行すると、パフォーマンスの問題が発生することです。

これをより効率的かつ迅速に実行するには、どのように最適化すればよいでしょうか? コードからわかるように、これには多くの部分があります。

$eventquery = mysql_query("SELECT * FROM maintable WHERE PCatID != '3' AND PCatID != '4'");
while($event = mysql_fetch_array($eventquery))
{
$querystring = null;
$performer_id = array();
$hasharray = array();
$venue = preg_replace("/ \([fF]ormerly (.+?)\)/", '', $event['Venue']);

$perfquery = mysql_query("SELECT * FROM maintable WHERE EventID = '".$event['EventID']."'");   
while($perf = mysql_fetch_array($perfquery))
    {
        $performer_id[$perf['PerformerID']] = $perf['Performer'];
        $hasharray[] = $perf['id'];
    }

$eventtime = getEventTime($event['DateTime']);
$performer_id = serialize($performer_id);
$hasharray = serialize($hasharray);

if($event['PCatID'] == "2" && $event['CCatID'] != "24")
{
    $request = "buy-".strCleanupForPage($event['Event'])."-concert-tickets/".strCleanupForPage($event['City'])."-".
        strCleanupForPage(stateabb($event['State']))."-".strCleanupForPage($venue)."-".$eventtime['date'];

    $catnum = "202";

    $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray, mainpage) VALUES 
        ('".$request."','".$catnum."','".addslashes($event['Event'])."','".addslashes($performer_id)."',
            '".$event['EventID']."','".$hasharray."','n')";


}
elseif($event['GCatID'] == "32" || $event['GCatID'] == "16" || $event['GCatID'] == "30" || $event['GCatID'] == "19" ||
         $event['GCatID'] == "31" || $event['GCatID'] == "22")
{ 
    if($event['GCatID'] == "32")
        {$catnum = "102";}
    elseif($event['GCatID'] == "16")
        {$catnum = "101";}
    elseif($event['GCatID'] == "30")
        {$catnum = "103";}
    elseif($event['GCatID'] == "19")
        {$catnum = "104";}
    elseif($event['GCatID'] == "31")
        {$catnum = "109";}
    elseif($event['GCatID'] == "22")
        {$catnum = "108";}
    elseif($event['GCatID'] == "17")
        {
            if($event['CCatID'] == "66")
                {$catnum = "106";}
            elseif($event['CCatID'] == "65")
                {$catnum = "105";}
        }

    if(strstr($event['Event']," vs. "))
        {
            $game = true;
            $teams = explode(" vs. ",$event['Event']);
        }
    elseif(strstr($event['Event']," Vs. "))
        {
            $game = true;
            $teams = explode(" Vs. ",$event['Event']);
        }
    else
        {
            $game = false;            
        }

    if($game)
        {           

            $catnum .= "2";
            $homequery = mysql_query("SELECT * FROM sportsteams WHERE fullname LIKE '".$teams[0]."'");  
            $home = mysql_fetch_array($homequery);  
            $awayquery = mysql_query("SELECT * FROM sportsteams WHERE fullname LIKE '".$teams[1]."'");  
            $away = mysql_fetch_array($awayquery);

            if((mysql_num_rows($homequery)) == 0 || (mysql_num_rows($awayquery)) == 0)
            {
                if($catnum == "1012")
                    {$request = "mlb-baseball-tickets";}
                elseif($catnum == "1022")
                    {$request = "nfl-football-tickets";}
                elseif($catnum == "1032")
                    {$request = "nba-basketball-tickets";}
                elseif($catnum == "1042")
                    {$request = "nhl-hockey-tickets";}
                elseif($catnum == "1052")
                    {$request = "ncaa-football-tickets";}
                elseif($catnum == "1062")
                    {$request = "ncaa-basketball-tickets";}
                elseif($catnum == "1082")
                    {$request = "mls-soccer-tickets";}
                elseif($catnum == "1092")
                    {$request = "wnba-basketball-tickets";}
                $eventname = preg_replace("/\([iI]ncludes (.+?)\)/", '', $event['Event']);
                $request .= "/".strCleanupForPage($eventname)."-".strCleanupForPage($event['City'])."-".
                     strCleanupForPage(stateabb($event['State']));
                }
            else
                {
                    $request = strCleanupForPage($home['fullname'])."-tickets-".strCleanupForPage($venue)."/".strCleanupForPage($home['nickname'])."-vs-".strCleanupForPage($away['nickname'])."-".strCleanupForPage($event['City'])."-".
                    strCleanupForPage(stateabb($event['State']))."-".$eventtime['date'];
                    $request = str_replace("-/","/",$request);
                }

        $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray, mainpage) VALUES 
        ('".$request."','".$catnum."','".addslashes($event['Event'])."','".addslashes($performer_id)."',
            '".$event['EventID']."','".$hasharray."','n')";
    }
    else
    {   
        $catnum .= "3";
        if($catnum == "1013")
            {$request = "mlb-baseball";}
        elseif($catnum == "1023")
            {$request = "nfl-football";}
        elseif($catnum == "1033")
            {$request = "nba-basketball";}
        elseif($catnum == "1043")
            {$request = "nhl-hockey";}
        elseif($catnum == "1053")
            {$request = "ncaa-football";}
        elseif($catnum == "1063")
            {$request = "ncaa-basketball";}
        elseif($catnum == "1083")
            {$request = "mls-soccer";}
        elseif($catnum == "1093")
            {$request = "wnba-basketball";}

        $eventname = preg_replace("/\([iI]ncludes (.+?)\)/", '', $event['Event']);
        $request .= "/".strCleanupForPage($eventname)."-".strCleanupForPage($event['City'])."-".
        strCleanupForPage(stateabb($event['State']));

        $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray, mainpage) VALUES 
        ('".$request."','".$catnum."','".addslashes($event['Event'])."','".addslashes($performer_id)."',
            '".$event['EventID']."','".$hasharray."','n')";
    }
}
elseif($event['CCatID'] == "50")
{
    $request = "boxing-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
    $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray) VALUES
        ('".$request."','1142','".addslashes($event['Event'])."','".addslashes($performer_id)."','".$event['EventID']."',
            '".$hasharray."')";
}    
elseif($event['CCatID'] == "67")
{
    $request = "golf-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
    $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray) VALUES
        ('".$request."','1112','".addslashes($event['Event'])."','".addslashes($performer_id)."','".$event['EventID']."',
            '".$hasharray."')";
}    
elseif($event['CCatID'] == "27")
{
    $request = "tennis-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
    $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray) VALUES
        ('".$request."','1102','".addslashes($event['Event'])."','".addslashes($performer_id)."','".$event['EventID']."',
            '".$hasharray."')";
}    
elseif($event['CCatID'] == "101")
{
    $request = "ufc-mma-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
    $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray) VALUES
        ('".$request."','1152','".addslashes($event['Event'])."','".addslashes($performer_id)."','".$event['EventID']."',
            '".$hasharray."')";
}    
elseif($event['CCatID'] == "69")
{
    if(strstr($event['Event'],"NASCAR"))
    {                    
        $request = "nascar-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
        $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray) VALUES
            ('".$request."','1122','".addslashes($event['Event'])."','".addslashes($performer_id)."','".$event['EventID']."',
            '".$hasharray."')";
    }
    elseif($event['GCatID'] == "35")
    {
        $request = "horse-racing-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
        $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray) VALUES
            ('".$request."','1132','".addslashes($event['Event'])."','".addslashes($performer_id)."','".$event['EventID']."',
            '".$hasharray."')";
    }
}
elseif($event['GCatID'] == "26")
{
    $request = "wwe-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
    $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray) VALUES
        ('".$request."','1162','".addslashes($event['Event'])."','".addslashes($performer_id)."','".$event['EventID']."',
            '".$hasharray."')";
}
elseif($event['CCatID'] == "24")
{   
    $catnum = "402";
    $request = strCleanupForPage($event['Event'])."-comedy-tickets/".strCleanupForPage($event['City'])."-".strCleanupForPage(stateabb($event['State'])).
        "-".strCleanupForPage($event['Venue'])."-".$eventtime['date'];
    $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray, mainpage) VALUES 
        ('".$request."','".$catnum."','".addslashes($event['Event'])."','".addslashes($performer_id)."',
            '".$event['EventID']."','".$hasharray."','n')";
}

if($querystring)
{
    $request = str_replace("--","-",$request);
    if(!mysql_query($querystring))
        {
            exit("<br>" . mysql_error());
        }
    else
    {
        if(mysql_affected_rows() != 0)
            {               
                echo date('H:i:s') . ": ";
                echo $request . " entry inserted<br>";
            }
        else
            {
                //echo "<i>" .$request . " entry ignored</i><br>";
            }
    }
}

}

どんな助けでも大歓迎です。前もって感謝します!

4

5 に答える 5

3

リファクタリングの機会を探している場合は、改善できる可能性のある領域を提供する一般的なコードの匂いがいくつかあります。

長い if / elseif/ else ステートメント:

if () {
    ...
} elseif () {
    ...
} else {
    ...
}

それらをステートメントに置き換えることを好む人もswitchいますが、オブジェクト指向にはこれを処理するためのより強力なツールがあります。場合によっては、適切に記述されたメソッドだけで、それらの必要性を減らすことができます。

あなたのコードで気付いたもう 1 つのことは、(一見) 異なる条件での重複したアクションです。

if(strstr($event['Event']," vs. "))
    {
        $game = true;
        $teams = explode(" vs. ",$event['Event']);
    }
elseif(strstr($event['Event']," Vs. "))
    {
        $game = true;
        $teams = explode(" Vs. ",$event['Event']);
    }

大文字と小文字を区別しない比較を行うと、5 行のほぼ同一のコードを節約できます。

if(stristr ($event['Event']," vs. "))
{
    $game = true;
    $teams = explode(" vs. ",$event['Event']);
}

関数内で if ステートメントを逆にすることで、ネストを減らして読みやすくすることができます。

if($querystring)
{
    // lots of code here
    // lots of code here
    // lots of code here
    // lots of code here
}

なる

if(!$querystring)
{
    return;
}

// lots of code here
// lots of code here
// lots of code here
// lots of code here

これは、入れ子が多いほど読みにくくなるため、if ステートメントを入れ子にしている場合に特に便利です。

パフォーマンスに関しては、データベースへのアクセスが増えるほど、コードの速度が低下します。クエリをバッチ処理するか、完全に回避できる場合、それはコードの中で使用ミリ秒単位で最もコストがかかる部分です!

パフォーマンスに関する注意: 最初にコードを最適化して読みやすくする必要があります。読みやすく、変更しやすいようにします。それからそれを測定します。時間がかかりすぎる場合は、パフォーマンス チューニングを検討してください。変更するたびに測定して、実際にパフォーマンスが向上するかどうかを確認します。

于 2012-09-28T16:24:05.813 に答える
1

オプションはこれを変更することです:

        $catnum .= "3";
    if($catnum == "1013")
        {$request = "mlb-baseball";}
    elseif($catnum == "1023")
        {$request = "nfl-football";}
    elseif($catnum == "1033")
        {$request = "nba-basketball";}
    elseif($catnum == "1043")
        {$request = "nhl-hockey";}
    elseif($catnum == "1053")
        {$request = "ncaa-football";}
    elseif($catnum == "1063")
        {$request = "ncaa-basketball";}
    elseif($catnum == "1083")
        {$request = "mls-soccer";}
    elseif($catnum == "1093")
        {$request = "wnba-basketball";}

そしてスイッチで書き直しますswitch

于 2012-09-28T16:17:26.987 に答える
1

EDIT1 : SQL インジェクションを回避するために以下のコードを更新しました (これにより、コードが短くなり、読みやすくなります)。

最大のパフォーマンスの向上は、 を介して一度に複数のレコードを挿入することINSERT INTO ... (fields) VALUES (values1),(values2)...です。次に例を示します。

$eventquery = mysql_query("SELECT * FROM maintable WHERE PCatID != '3' AND PCatID != '4'");
$page_fields = array();
while($event = mysql_fetch_array($eventquery))
{
    $querystring = null;
    $performer_id = array();
    $hasharray = array();
    $venue = preg_replace("/ \(formerly (.+?)\)/i", '', $event['Venue']);

    $perfquery = mysql_query("SELECT * FROM maintable WHERE EventID = '".$event['EventID']."'");   
    while($perf = mysql_fetch_array($perfquery))
        {
            $performer_id[$perf['PerformerID']] = $perf['Performer'];
            $hasharray[] = $perf['id'];
        }

    $eventtime = getEventTime($event['DateTime']);
    $performer_id = serialize($performer_id);
    $hasharray = serialize($hasharray);

    if($event['PCatID'] == "2" && $event['CCatID'] != "24")
    {
        $request = "buy-".strCleanupForPage($event['Event'])."-concert-tickets/".strCleanupForPage($event['City'])."-".
            strCleanupForPage(stateabb($event['State']))."-".strCleanupForPage($venue)."-".$eventtime['date'];

        $catnum = "202";

        $page_fields[] = array($request, $catnum, $event['Event'], $performer_id, $event['EventID'], $hasharray, 'n');
    }
    elseif($event['GCatID'] == "32" || $event['GCatID'] == "16" || $event['GCatID'] == "30" || $event['GCatID'] == "19" ||
             $event['GCatID'] == "31" || $event['GCatID'] == "22")
    { 
        if($event['GCatID'] == "32")
            {$catnum = "102";}
        elseif($event['GCatID'] == "16")
            {$catnum = "101";}
        elseif($event['GCatID'] == "30")
            {$catnum = "103";}
        elseif($event['GCatID'] == "19")
            {$catnum = "104";}
        elseif($event['GCatID'] == "31")
            {$catnum = "109";}
        elseif($event['GCatID'] == "22")
            {$catnum = "108";}
        elseif($event['GCatID'] == "17")
            {
                if($event['CCatID'] == "66")
                    {$catnum = "106";}
                elseif($event['CCatID'] == "65")
                    {$catnum = "105";}
            }

        if(strstr($event['Event']," vs. "))
            {
                $game = true;
                $teams = explode(" vs. ",$event['Event']);
            }
        elseif(strstr($event['Event']," Vs. "))
            {
                $game = true;
                $teams = explode(" Vs. ",$event['Event']);
            }
        else
            {
                $game = false;            
            }

        if($game)
            {           

                $catnum .= "2";
                $homequery = mysql_query("SELECT * FROM sportsteams WHERE fullname LIKE '".$teams[0]."'");  
                $home = mysql_fetch_array($homequery);  
                $awayquery = mysql_query("SELECT * FROM sportsteams WHERE fullname LIKE '".$teams[1]."'");  
                $away = mysql_fetch_array($awayquery);

                if((mysql_num_rows($homequery)) == 0 || (mysql_num_rows($awayquery)) == 0)
                {
                    if($catnum == "1012")
                        {$request = "mlb-baseball-tickets";}
                    elseif($catnum == "1022")
                        {$request = "nfl-football-tickets";}
                    elseif($catnum == "1032")
                        {$request = "nba-basketball-tickets";}
                    elseif($catnum == "1042")
                        {$request = "nhl-hockey-tickets";}
                    elseif($catnum == "1052")
                        {$request = "ncaa-football-tickets";}
                    elseif($catnum == "1062")
                        {$request = "ncaa-basketball-tickets";}
                    elseif($catnum == "1082")
                        {$request = "mls-soccer-tickets";}
                    elseif($catnum == "1092")
                        {$request = "wnba-basketball-tickets";}
                    $eventname = preg_replace("/\([iI]ncludes (.+?)\)/", '', $event['Event']);
                    $request .= "/".strCleanupForPage($eventname)."-".strCleanupForPage($event['City'])."-".
                         strCleanupForPage(stateabb($event['State']));
                    }
                else
                    {
                        $request = strCleanupForPage($home['fullname'])."-tickets-".strCleanupForPage($venue)."/".strCleanupForPage($home['nickname'])."-vs-".strCleanupForPage($away['nickname'])."-".strCleanupForPage($event['City'])."-".
                        strCleanupForPage(stateabb($event['State']))."-".$eventtime['date'];
                        $request = str_replace("-/","/",$request);
                    }

            $page_fields[] = array($request, $catnum, $event['Event'], $performer_id, $event['EventID'], $hasharray, 'n');
        }
        else
        {   
            $catnum .= "3";
            if($catnum == "1013")
                {$request = "mlb-baseball";}
            elseif($catnum == "1023")
                {$request = "nfl-football";}
            elseif($catnum == "1033")
                {$request = "nba-basketball";}
            elseif($catnum == "1043")
                {$request = "nhl-hockey";}
            elseif($catnum == "1053")
                {$request = "ncaa-football";}
            elseif($catnum == "1063")
                {$request = "ncaa-basketball";}
            elseif($catnum == "1083")
                {$request = "mls-soccer";}
            elseif($catnum == "1093")
                {$request = "wnba-basketball";}

            $eventname = preg_replace("/\([iI]ncludes (.+?)\)/", '', $event['Event']);
            $request .= "/".strCleanupForPage($eventname)."-".strCleanupForPage($event['City'])."-".
            strCleanupForPage(stateabb($event['State']));

            $page_fields[] = array($request, $catnum, $event['Event'], $performer_id, $event['EventID'], $hasharray, 'n');
        }
    }
    elseif($event['CCatID'] == "50")
    {
        $request = "boxing-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
        $catnum = '1142';
        $page_fields[] = array($request, $catnum, $event['Event'], $performer_id, $event['EventID'], $hasharray, 'n');
    }    
    elseif($event['CCatID'] == "67")
    {
        $request = "golf-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
        $catnum = '1112';
        $page_fields[] = array($request, $catnum, $event['Event'], $performer_id, $event['EventID'], $hasharray, 'n');
    }    
    elseif($event['CCatID'] == "27")
    {
        $request = "tennis-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
        $catnum = '1102';
        $page_fields[] = array($request, $catnum, $event['Event'], $performer_id, $event['EventID'], $hasharray, 'n');
    }    
    elseif($event['CCatID'] == "101")
    {
        $request = "ufc-mma-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
        $catnum = '1152';
        $page_fields[] = array($request, $catnum, $event['Event'], $performer_id, $event['EventID'], $hasharray, 'n');
    }    
    elseif($event['CCatID'] == "69")
    {
        if(strstr($event['Event'],"NASCAR"))
        {                    
            $request = "nascar-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
            $catnum = '1122';
            $page_fields[] = array($request, $catnum, $event['Event'], $performer_id, $event['EventID'], $hasharray, 'n');
        }
        elseif($event['GCatID'] == "35")
        {
            $request = "horse-racing-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
            $catnum = '1132';
            $page_fields[] = array($request, $catnum, $event['Event'], $performer_id, $event['EventID'], $hasharray, 'n');
        }
    }
    elseif($event['GCatID'] == "26")
    {
        $request = "wwe-tickets/".strCleanupForPage($event['Event'])."-".strCleanupForPage($event['City'])."-".$eventtime['date'];
        $catnum = '1162';
        $page_fields[] = array($request, $catnum, $event['Event'], $performer_id, $event['EventID'], $hasharray, 'n');
    }
    elseif($event['CCatID'] == "24")
    {   
        $catnum = "402";
        $request = strCleanupForPage($event['Event'])."-comedy-tickets/".strCleanupForPage($event['City'])."-".strCleanupForPage(stateabb($event['State'])).
            "-".strCleanupForPage($event['Venue'])."-".$eventtime['date'];
        $page_fields[] = array($request, $catnum, $event['Event'], $performer_id, $event['EventID'], $hasharray, 'n');
    }

    if($page_fields)
    {
        $rows = array();
        foreach ($page_fields as $fields) {
            for ($i = 0; $i < count($fields), ++$i) {
                $fields[$i] = sprintf("'%s'", mysql_escape_string($fields[$i]));
            }
            $rows[] = sprintf('(%s)', join(',', $fields));
        }
        $querystring = "INSERT IGNORE INTO pages (request, catnum, name, perfarray, event_id, hasharray, mainpage) VALUES\n"
            . join(",\n", $rows);

        $request = str_replace("--","-",$request);
        if(!mysql_query($querystring))
            {
                exit("<br>" . mysql_error());
            }
        else
        {
            if(mysql_affected_rows() != 0)
                {               
                    echo date('H:i:s') . ": ";
                    echo $request . " entry inserted<br>";
                }
            else
                {
                    //echo "<i>" .$request . " entry ignored</i><br>";
                }
        }
    }

}

もちろん、システムに設定された制限に達した場合は、max_allowed_packetおよび/またはbulk_insert_buffer_size設定を微調整する必要があります。

于 2012-09-28T16:18:42.087 に答える
0

そんなに長くないの?また、コードの複雑さを軽減したい場合は、大規模なアプリで、オブジェクト指向プログラミングに切り替えてください。mysql_queryなどの非推奨の関数をまだ使用しています。サポートは削除されていませんが、使用はお勧めしません。よりオブジェクト指向のアプローチに切り替えます。PDOが最適です

于 2012-09-28T16:10:12.480 に答える
0

あなたのデータベース構造はひどく奇妙に思えますが、あなたのコードはかなり読みにくいので、私は間違っている可能性があります。

1 つの問題は、正規化されていないことです。の場合、maintable1 つのイベントに対して複数の選択を行う必要があります。まず、メイン テーブルの名前を変更してから、イベントとそのイベントに直接関連するデータのみを保持する必要があります。

参加しているパフォーマーまたはチームについては、イベント ID とパフォーマー データを保持する別のテーブル (おそらくこのスクリプトの結合を使用) をクエリする必要があります。

カテゴリ ID もデータベースにある必要があり、最初のクエリで結合することもできます。異なる処理を行うカテゴリ プロパティも、このテーブルに格納します。

あなたの問題は、1万行あることではなく、データベース構造です。

データベースの正規化と、特に第 3 正規形について読んでください。その後、試してみて、お気軽に戻って結果についてお尋ねください。

于 2012-09-28T16:32:39.523 に答える