views:

261

answers:

2

Using Delphi 2009 + Firebird 2.1.3.

Database is ODS 11.1, default char set is UTF8.

My prepared query is as follows:

SELECT 
  a.po_id, a.po_no 
FROM 
  purchase_order a
WHERE EXISTS 
  (SELECT 1 
   FROM 
     sales_order_item z1
   JOIN 
     purchase_order_item z2 
   ON 
     z2.so_item_id = z1.so_item_id
   AND 
     z2.po_id = a.po_id
   WHERE z1.so_id = :soid)
ORDER BY a.po_no

Now when I loop this say 1000 times because I have 1000 x so_id, the CPU usage get at 100% for FBSERVER.EXE

Anyone encountered this problem?

+2  A: 

Try this instead:

  SELECT po.po_id, 
         po.po_no 
    FROM PURCHASE_ORDER po
    JOIN PURCHASE_ORDER_ITEM poi ON poi.po_id = po.po_id
    JOIN SALES_ORDER_ITEM soi ON soi.so_item_id = poi.so_item_id
                             AND soi.so_id = :soid
ORDER BY po.po_no
OMG Ponies
With this query, I could get duplicate PO_NOs. I could add DISTINCT but then it would be expensive for the CPU right?
Atlas
@Atlas: Corrected - I misread the joins.
OMG Ponies
In your variant of the SELECT you're referencing "a.po_id" from the outer select, and this forces Firebird to run your second query for every line in the "purchase_order" table (look at the query plan). Removing the "z2.po_id = a.po_id" might help a bit, allowing Firebird to run the second query first, sort it, cache the result and then run the first query and do lookups in that result set. If you use OMG's variant and use "DISTINCT" you're allowing the Firebird query optimizer to do it's best, and Firebird will then sort the result set and you'd be fine.
Cosmin Prund
A: 

Do a gstat -h from your databes and see the difference between Oldest Transaction and Next Transaction.

The difference between this two numbers is haw many transacrtions are open.

  • If you see to many, your problem could be than you are not commiting them.

  • It could also be than you open one transaction and it interferes with the other ones.

Finally, could you do this SELECT in a read-only transaction.

Duilio Juan Isola