MySQL monster query is timing out. Anything I can do about it? (Long question, possible a cure for insomnia.)
I set up (using my usual mediocre coding skills) a small PHP app which allows form creation, saves the results, and outputs the results into a tab-delimited file. First two parts seem to work fine. Having some trouble with the last bit.
The form information is saved into two tables: "form" which saves the name, etc., of each individual form, and "field" which saves the fields, using the 'form' row id to keep track of where they belong. A simple form might be saved as
form -> form_id=1, form_name='Test', etc.
field -> field_id=1; field_form=1; field_label='First Name', etc.
field -> field_id=2; field_form=1; field_label='Last Name', etc.
Pretty basic stuff. Likewise, when the form is filled out, the data goes into two tables, "form_save", and "field_save" which mimics the structure above. The 'field_save' row has a column pointing to both the id of the 'form_save' row and 'field' row it is associated with. In essence, for every form in the database, there is one row in 'form' and however many rows in 'field'. For every form someone fills out, there is one row in 'form_save' and however many rows in 'field_save'.
This all works fine on modest forms filled out in reasonable numbers, which is mostly what my clients have. However, a client created a monster 100 question form and has had a large number of people filling it out. It can be edited on the back-end and saved on the front-end just fine, but I cannot get it to spit out a tab-delimited report because the way I'm approaching it in PHP either requires a cajillion queries or a cajillion if/then reiterations to process. This times out on the server, which has time limits on queries.
The "simplest" way to grab results seems to be to:
* Query grabbing all of the 'field' rows for the form type.
* Query grabbing all of the 'field_save' rows which match the form type.
Then it gets ugly. Step through all of the 'form_save' rows, and within that step through the 'field' rows, looking for matches. It works on reasonable results sets but on a form with 100 fields (really) with 15,000 people who have filled it out (really) we're talking about 1.5 million loops. Boom.
My results file looks like this:
[date] [ip] [first name] [last name] [another optional] [another required] [another required] [another optional] etc.
With the date and IP coming from 'form_save'and the rest coming from 'field_save', as matched against the 'field' rows for that particular form. Fields which are optional to fill out may have no saved result in the 'field_save' table and therefore need a tab to keep the columns aligned.
Is there any way I can structure a query to return results combing the 'form_save' and 'field_save' data all in a single neat row, as above, including the "empty" slots which may exist? Or is there a smarter way of doing what I'm doing?
(I think I can move this client to a dedicated box, which would allow my program to run, but it bugs me that I think I'm being horribly inefficient here and would love some pointers on doing a better job with the query.)
posted by pompomtom at 9:17 PM on November 19, 2007