2010-03-05 15 views
1

Utilisation de Delphi 2009 + Firebird 2.1.3.Firebird 2.1 + EXISTS = bug de requête?

La base de données est ODS 11.1, le jeu de caractères par défaut est UTF8.

Ma requête préparée est la suivante:

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 

Maintenant, quand je boucle ce dire 1000 fois parce que j'ai 1000 x so_id, l'utilisation du processeur obtenir à 100% pour fbserver.exe

Toute personne rencontrée ce problème?

Répondre

2

Essayez ceci:

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 
+0

Avec cette requête, je pourrais obtenir des PO_NO en double. Je pourrais ajouter DISTINCT, mais alors ce serait coûteux pour le CPU à droite? – Atlas

+0

@Atlas: Corrigé - J'ai mal interprété les jointures. –

+0

Dans votre variante de SELECT, vous faites référence à "a.po_id" dans la sélection externe, ce qui oblige Firebird à exécuter votre deuxième requête pour chaque ligne de la table "purchase_order" (voir le plan de requête). Supprimer le "z2.po_id = a.po_id" pourrait aider un peu, permettant à Firebird d'exécuter la deuxième requête en premier, de trier, de mettre en cache le résultat, puis d'exécuter la première requête et d'effectuer des recherches dans cet ensemble de résultats. Si vous utilisez la variante OMG et que vous utilisez "DISTINCT", vous permettez à l'optimiseur de requêtes Firebird de faire de son mieux, et Firebird triera alors le jeu de résultats et tout ira bien. –

0

Faites un gstat -h de vos databes et voir la différence entre plus ancienne transaction et la transaction suivante.

La différence entre ces deux nombres est que beaucoup de transacrtions sont ouvertes.

  • Si vous voyez à beaucoup, votre problème pourrait être que vous ne les commettez pas.

  • Il se peut aussi que vous ouvriez une transaction et qu'elle interfère avec les autres.

Enfin, pourriez-vous le faire SELECT dans une transaction en lecture seule.