Forum Moderators: phranque

Message Too Old, No Replies

Load from db, or from array

trying to trim process overhead

         

grandpa

10:58 pm on Apr 2, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I have a page that loads form data from MySql. The page is constructed with php. This process is repeated a couple of dozen times on the page, and you can actually watch each form build as the page loads.

Each time I load the data I'm performing a while loop with a specific query to the database. This looks and feels like a lot of processing overhead.

I'm considering an alternative method, loading the info from the database one time, into an array, then populating each form from the array. (I've toyed with this idea a little, and have more to learn about php array processing yet.)

A few statistics. The database contains over 12K records. Each form contains appx 300+ items. Each query is specific to the form. Here's a sample query:
$sql = "SELECT * FROM table WHERE status = 'A' AND prodgrp = '11' AND prodtyp = ' ' AND prodqty = '5' ORDER BY desclong";

I would change prodgrp, prodtyp or prodqty, depending on the form.

Is there a better way to handle this amount of data and not have to run a query for each form?

ara818

9:45 am on Apr 3, 2004 (gmt 0)

10+ Year Member



Yeah, querying your database dozens of times per pageload is not a good idea.

I'm afraid I don't quite understand why you need to run so many queries to fill in the form info, but if you can avoid it do so!

If you give me a more in depth example I may be able to give you a better strategy.

grandpa

10:42 am on Apr 3, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm afraid I don't quite understand why you need to run so many queries to fill in the form info, but if you can avoid it do so!

It's so easy to want to say, look at the page...
...instead, let me try to explain.

I sell a widget that comes pre-packaged in 3 quantities.
You can get a pack of 5, 20 or 100. Each of those packs comes in 330 different varities. The first form will list all the varities for the 5 pack, the next form handles all the varities for the 20 pack, and so on thru the page.

If you look at my query select, the status check limits the results to only 'Active' items. Right now that's over 300 and is expected to double in the not too distant future.

The prodgrp part of the query can be one of 7 different groups. The prodtyp part of the query will be one of 3 product types. Finally, the prodqty item will be one of three available quantites for that widget.

So, each form on the page is dedicated to the specific parameters that make up the particular widget in that form.

Now for an example:
Lets say the first form is used for my 'Brown Widgets' which are sold in 5 packs. I populate a drop down box in that form that lists every variety of Brown Widget, ie., fuzzy, hairy, bald, round, flat... up to 330 varieties. That drop down box is populated from the database.

The next form then handles the same Brown Widget, except this is the 20 pack. The next form handles the same Brown Widget in 100 packs.

The next 3 forms handle Blue Widgets is the manner described for Brown Widgets. Then on to Red Widgets, Purple Widgets, etc.

On another site I've done all this differently, and it works pretty good. But on this site I have a little more latitude to experiment, so I'm trying to overcome some of the difficulties I've experienced on the first site. But the cost of overhead seems to be too high. I'm fishing for ideas about how to trim that overhead.

coopster

4:42 pm on Apr 3, 2004 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



If the data can be sorted as it is coming out, why not use some form of control structure to handle your select list build? Let's say for example, your data is being pulled somewhat like this...

prodgrp prodqty prodtyp
Blue....5.......bald
Blue....5.......fuzzy
Blue....5.......hairy
Blue....20......bald
Blue....20......fuzzy
Blue....20......hairy
Blue....100.....bald
Blue....100.....fuzzy
Blue....100.....hairy
Red.....5.......bald
Red.....5.......fuzzy
Red.....5.......hairy
Red.....20......bald
Red.....20......fuzzy
Red.....20......hairy
Red.....100.....bald
Red.....100.....fuzzy
Red.....100.....hairy

I would pull the data in a single query and build all of the select lists on the fly using a PHP control structure:

// Initialize some variables:
$selections = ''; // our entire group of select lists
$prodgrp = '';
$prodqty = '';
$sql = "SELECT prodgrp, prodqty, prodtyp from products";
$rows = mysql_query($sql);
while ($row = mysql_fetch_assoc($rows)) {
if ($prodgrp <> $row['prodgrp'] OR $prodqty <> $row['prodqty']) {
// close the previous group, if any:
if ($selections) $selections .= '</select>';
// establish our new control variables:
$prodgrp = $row['prodgrp'];
$prodqty = $row['prodqty'];
// start a new select list:
$selections .= '<select name="' . $prodgrp . $prodqty . '">';
}
$selections .= '<option value="' . $prodgrp . $prodqty . '">';
$selections .= $prodgrp . $prodqty;
$selections .= '</option>';
}
// close on the last row read in the while loop, if any existed:
if ($selections) $selections .= '</select>';

I just threw this code down here, meaning it hasn't been tested, but hopefully you understand what I am trying to show here. Is this a possiblity for you grandpa?

figment88

4:58 pm on Apr 3, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You've already gotten some good feedback on the php, I'd like to add:

1) your sql selects on multiple fields, make sure you have indexes on all of them.

2) other than adding new products and fixing errors, it doesn't sound like this data changes much. Should it really be processed dynamically? For the way this site sounds, I would most likely store the data in a database and generate static pages from it when the underlying data changes.

ara818

10:53 pm on Apr 3, 2004 (gmt 0)

10+ Year Member



What coopster recommended is exactly right IMHO, it seems like you can sort the data pretty easily coming from the DB. Ater that point just about ANY amount of processing you need to do in PHP to construct the multiple form fields from the that one query's output will be many, many times faster than doing dozens of DB queries.

grandpa

11:16 pm on Apr 3, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



coopster, I read your post several times and it began to make sense. I'll start work on Ver. C later today and let you know how it goes.

figment, I assume by static you mean all the options in a select group on the form are hard coded on the page. Then just create a new page when the data changes?

The static page takes about 45 seconds to load over a DSL connection. (OK, so right now the php version isn't much better...) Also, this is just one page that uses this db information. What I've managed to do so far by using MySql is eliminate the need to edit several pages every time we add a new widget, or even temporarily de-activate a widget if it becomes unavailable. I make copies of my loaded page in the event the db becomes unusable for any reason; I can pop in the static copy. For a comparison, the php version of this page is 45Kb, the static version of the same page is 896Kb. Seems like a comparison of apples to oranges, since when the page loads it will load all 896K no matter what source it comes from...

I know all the fields I use for my selects are not indexed. So maybe before I get too much farther along I'll add some indexes and see how much of a performance boost I can get.

I appreciate the feedback. Now to get to work.

figment88

12:21 am on Apr 4, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Another place I know people will disagree with me on is relaxing HTML standards for large pages.

At 896kb, I think you want to save wherever you can.

For example, I'd things like
1) drop closing option tags </option>
2) drop single and double quotes
3) drop value paramaters on the options and read the text label or index
4) get rid of most formatting character (newlines, tabs, spaces)

These tactics make for crappy HTML but you can get pages to load faster.

grandpa

9:34 am on Apr 5, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



figment, I'm afraid the bulk of that page size is data.. it will only get bigger. I cut out about 50K with a better query. Not much, it seems, but the page loads fairly quick.

coopster, I started from the base you provided, and several hours later I have something that looks completely different. Go figure...

It seems the most critical part to this page is the query itself. I ordered my data by the qty, group, and type , then in my while loop I used if, elseif statements to build arrays. Each array contains the option groups for every widget, based on a unique combination of qty, group & type.

Here's what it looks like:

$sql = "SELECT * from products WHERE status = 'A' ORDER BY prodqty, prodgrp, prodtyp ";

$rows = mysql_query($sql);
while ($row = mysql_fetch_assoc($rows)) {
$wkqty = $row['prodqty'];
if ($wkqty == '1') {
$arrA[$wkc] = "<option stuff here>and here</option>";
$wkc ++;
}
else if ($wkqty == '5') {
$arrB[$wkc] = "<option stuff here>and here</option>";
$wkc ++;
}
//more else if here, for each qty, group, type combination
} //end while

Then, in each form, I've placed this line of code:
foreach ($arrA as $val) echo " $val ";

It's just a matter of matching up the arrays to the forms.
I don't think this is quite as elegant as it was supposed to turn out? Since I'm building 24 arrays now, I assume all that data is being stored in memory on my server? Is there a parameter for MySQL that can bite me if say, 10 people are surfing the page at the same time? 20 people?

While I almost completely understand coopsters solution, one thing I haven't figured out yet is how to present the right $selections to a specific form. I'm going to try to tackle it again. I was beginning to see it work when I got blindsided by those arrays :-)

Oh, the database is indexed in the same way I use ORDER BY in the select statement. First index is qty, then group, then type.