Обсуждение: Selecting with a large number of foreign keys
I didn't get any answers from the -novice list, maybe you folks know? In my call tracking database, I have quite a few fields that are numbers representing primary keys in a number of smaller tables; these are used when there is a drop-down list of choices that someone can pick from. My problem is that when I do reports on these, I want to see the name of the selection instead of the number. I tried doing this with the following query (which seems to work well for a small number of these fields): SELECT call_table.field_one,call_table.field_two,field_three_table.name AS field_three WHERE field_three_table.id = call_table.field_three; However, when I start doing this with a LOT of fields, I notice the backend process growing extremely large (just pulling up all the calls for two days with 20 fields selected resulting in the backend growing > 50 MB and taking a loooong time.) Is there a better way to do these? -- Matt Behrens <matt@iserv.net> Network Operations Center, The Iserv Company
Matt - We've been running into exactly the same problems you, for exactly the same reason: we have a highly 'normalized' database design, in order to easily populate drop-downs and picklists (get the users to enter the right data by only giving them the right data!) You don't mention what version of PostgreSQL you're using, but I bet it's 6.4.2. The development team found some nasty problems in the query optimzer that caused exactly these symptoms, and there are fixes in v6.5beta. The way to test if this is the problem is to try your query at the psql prompt, then try an EXPLAIN of your query. IF the EXPLAIN takes a long time (and a lot of memory), bingo! One workaround until you can upgrade (the beta is shaking out bugs right now) is to enable the Genetic Query Optimizer at a small number of tables. This sort of short circuits the problem. Note that the WinODBC driver disables GQO by default (if you're using that) via SQL, do: SET GEQO TO 'ON=5'; or some other small number: it's the number of tables in a 'join' at which GEQO will take over. HTH, Ross Matt Behrens wrote: > <problem with large joins blowing up> -- Ross J. Reedstrom, Ph.D., <reedstrm@rice.edu> NSBRI Research Scientist/Programmer Computer and Information Technology Institute Rice University, 6100 S. Main St., Houston, TX 77005
"Ross J. Reedstrom" <reedstrm@rice.edu> writes: > Matt - > We've been running into exactly the same problems you, for exactly the > same reason: we have a highly 'normalized' database design, in order to > easily populate drop-downs and picklists (get the users to enter the > right data by only giving them the right data!) You don't mention what > version of PostgreSQL you're using, but I bet it's 6.4.2. The > development team found some nasty problems in the query optimzer that > caused exactly these symptoms, and there are fixes in v6.5beta. I think Ross has the right idea --- the 6.4.x optimizer has serious problems for queries that require joining more than about ten tables (since the number of possible ways to do the joins grows exponentially). GEQO is better but can still take an unreasonably long time. Although 6.5 is considerably quicker than 6.x, I still suspect that planning a 20-way join will take way longer than you'd like it to. If you have some kind of application in front of your database, you can avoid the need for the join planning by just retrieving the raw data and doing the substitutions at the application end, using local copies of the data from the auxiliary tables. I do this extensively in my own company's apps and it works just fine. (You pretty much need a local copy of each table anyway if you're going to present choices in popup menus...) regards, tom lane