开发者

Performance issue when querying a large xml file through php/ajax on Apache Server

I have a simple "live search" (resu开发者_运维技巧lts displayed while typing) web site. This make up is Ajax to PHP querying a pretty large XML document (10,000+ lines). This is all been hosted on a local Apache server (xamp). The scale of the xml document seems to be causing huge performance issue with results taking 10ish seconds to give the results.

I'm very new to PHP (this actually being my first play about) so there below is a snippet of code in case there is something obvious

    for($i=0; $i<($foodListXML->length); $i++){
  $type=$foodListXML->item($i)->getElementsByTagName('type');
  $foodnote=$foodListXML->item($i)->getElementsByTagName('foodnote');
  $style=$foodListXML->item($i)->getElementsByTagName('style');

  if ($type->item(0)->nodeType==1)
    {
    //find a link matching the search text
    if (stristr($type->item(0)->childNodes->item(0)->nodeValue,$q)){
     $currentFoodName = $type->item(0)->childNodes->item(0)->nodeValue;
     $currentFoodStyle = $style->item(0)->childNodes->item(0)->nodeValue;
     $currentFoodNote = $foodnote->item(0)->childNodes->item(0)->nodeValue;

      if ($hint==""){
        $hint= $currentFoodName . " , " . $currentFoodNote .  " , <b>" . $currentFoodStyle. "</b>" .   "<br>" ;
        }
      else{
        $hint=$hint . $currentFoodName . " , " . $currentFoodNote . " , <b>" . $currentFoodStyle. "</b>" .   "<br>" ;
        }

      }
    }
  }
}

Also if having the data in a DB and accessing that is faster, then I'm open to that.. All ideas really!!

Thanks.

UPDATE

As requested, here is the XML, and as stated the below times 1000 ;)

 <foodtype>
  <type>Pigeon,cooked</type >
  <foodnote>1 oz.</foodnote >
  <foodStyle>Crisp, Blah</foodStyle >
 </foodtype>


Dude. Deffo use the database.

If you have a 10,000+ lined XML, for looping will of course take a long time, and if/else statements can be expensive at that level.

databases are designed for such a query and will take a fraction of a second to get the information.

Additionally, doing this multiplied by the maount of users doing it - if they all use the XML scan function, you'll have your server kicking a screaming before night fall.


Man, you definitely need to read an old article from one of SO founders, Joel Spolsky Back to basics
It explains the things very well


I'm gonna bet a lot of your speed problems are related to the fact you're iterating through and getting some members of each entry, every time the search updates.

I'm not sure how your XML file is set up (you might want to post a snippet, just so we don't have to guess from the code), but loading it into memory and PHP arrays when the page loads (or even when the server starts, if you can keep it cached), then grabbing from there might be a better solution.

You also mention you're using AJAX. Any chance you could send it all to the client and allow a script on their end to handle the lookups (similar to the javascript search in Doxygen documentation). That will take the load off your server and may be a simpler solution (you'll just send a script and the XML file over).

Edit: And if absolutely none of that is possible, this code should be a touch faster:

for($i=0; $i<($foodListXML->length); $i++)
{
    $type=$foodListXML->item($i)->getElementsByTagName('type');
    if ($type->item(0)->nodeType==1)
    {
        // move these in here, so if the nodeType is wrong, don't bother looking them up
        $foodnote=$foodListXML->item($i)->getElementsByTagName('foodnote');
        $style=$foodListXML->item($i)->getElementsByTagName('style');

        //find a link matching the search text
        if (stristr($type->item(0)->childNodes->item(0)->nodeValue,$q))
        {
            $currentFoodName = $type->item(0)->childNodes->item(0)->nodeValue;
            $currentFoodStyle = $style->item(0)->childNodes->item(0)->nodeValue;
            $currentFoodNote = $foodnote->item(0)->childNodes->item(0)->nodeValue;

            if ($hint=="")
            {
                $hint= $currentFoodName . " , " . $currentFoodNote .  " , <b>" . $currentFoodStyle. "</b>" .   "<br>" ;
            } else {
                $hint=$hint . $currentFoodName . " , " . $currentFoodNote . " , <b>" . $currentFoodStyle. "</b>" .   "<br>" ;
            }
        }
    }
}


I'm not sure what the question was so I'll address your comment about a database: if your goal is to lookup something in that 10,000+ lines of data, then yes, a database will easily be a hundred or a thousand times more performant than your current solution.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜