stu@jpusa1.UUCP (03/20/87)
I'm trying to do what should be a simple update and can't believe the
abysmal performance. Maybe I'm missing something obvious. The scenario
is a 3 table database (name,address,accounts) and I'm updating a batch
from a fourth table. Here's the code to do the name:
update name_table
set name = (select name from change_table where
name_table.id = change_table.id)
where name_table.id in
(select id from change_table);
This seems overly complex when all I want to do is find the entries in
the name_table whose id match those in the change_table and update the
name column (field). If I leave the second where/select out, the
entries that don't match get thier name's nulled but this scheme seems
to require sizeof name_table * sizeof change_table querries. The bad
news is that a 3 table update takes about 36 seconds per transaction and
an 1800 row batch took 14 hours!!! Am I doing something wrong? Please
e-mail any advice/hints/ideas. I've already looked at unify and
informix and need to stay with an sql product that will run on an a.t.
under xenix or microport.
Thanks in advance.
Stu Heiss {...!ihnp4!jpusa1!stu}
--
Stu Heiss {gargoyle,ihnp4}!jpusa1!stugaryp@cognos.UUCP (Gary Puckering) (03/25/87)
In article <276@jpusa1.UUCP> stu@jpusa1.UUCP (Stu Heiss) writes: >I'm trying to do what should be a simple update and can't believe the >abysmal performance. Maybe I'm missing something obvious. The scenario >is a 3 table database (name,address,accounts) and I'm updating a batch >from a fourth table. Here's the code to do the name: > update name_table > set name = (select name from change_table where > name_table.id = change_table.id) > where name_table.id in > (select id from change_table); >This seems overly complex when all I want to do is find the entries in >the name_table whose id match those in the change_table and update the >name column (field). Wow! This is scarey! I hope someone can come up with an elegant SQL request for this. I can't think of one. However, I can offer a suggestion and a comment: 1. You *must* have an index on the id column of change_table. Otherwise, a sequential scan of change_table will be required for every row read from name_table. 2. The strategy SQL has forced you into is a bad one. You should be able to drive the update request from the change_table, rather than from the name_table. For examplem, in QTP, our 4GL transaction processor, you would code this request as: access change_table link to name_table output name_table update item name final name of change_table go For this request to execute efficiently, their need only be an index on id of name_table. Essentially, this request does a natural join of change_table and name_table and then it updates only the name_table row. Unfortunately, I can't see any way to do this in interactive SQL. 3. This above strategy could be accomplished within a program by using cursor. For example: sql declare get_changes cursor for select id.change_table name.change_table into :xid :xname from change_table, name_table where id.change_table = id.name_table Now you can code a loop which fetches the appropriate id's and names into host variables xid and xname. Within the loop you code an SQL update request like: sql update name_table set name = :xname where id = :xid Like I say, I hope someone else can come up with a decent solution which can be coded in interactive SQL. If not, it just goes to show you that SQL is a lousy excuse for a 4GL. It leads to counter-intuitive requests. -- Gary Puckering 3755 Riverside Dr. Cognos Incorporated Ottawa, Ontario decvax!utzoo!dciem! (613) 738-1440 CANADA K1G 3N3 nrcaer!cognos!garyp