0

我有一个脚本,它从一个表中获取信息,确定它是否需要为另一个表创建条目(避免重复),然后将信息插入到 pages 表中。问题是,以当前编码的方式查询大约 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语句替换它们,但面向对象有更强大的工具来处理这个问题。有时,只需一个写得好的方法就可以减少对它们的需求。

我在您的代码中注意到的另一件事是(看似)不同条件下的重复操作:

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

如果您进行不区分大小写的比较,您将节省五行几乎相同的代码

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

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 回答
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 回答
0

Your database structure seems terribly strange, however I could be wrong as your code is rather horrible to read.

One problem is that it's not normalized. For the maintable you have to do several selects for 1 event. Well, your main table should firstly change name and then hold only events and the data directly related to only the event.

For performers or teams participating you want to query another table (probably with a join for this script) which holds the event id together with the performers data.

Your category IDs should also be in the database and can also be joined in the first query. Any category properties that makes handling different you would also store in this table.

Your problem is not that you have 10k rows, it is the database structure.

Read up on database normalization and especially third normal form. Then give it a good try and feel free to come back and ask about the result.

于 2012-09-28T16:32:39.523 回答
0

不是很长吗?如果你想降低代码的复杂性,在大型应用程序中,切换到面向对象的编程。您仍在使用不推荐使用的函数,例如 mysql_query。它的支持尚未删除,但不鼓励使用。切换到更面向对象的方法。PDO 最好

于 2012-09-28T16:10:12.480 回答