2009-12-08 5 views
2

Nous rencontrons des problèmes de performances majeurs lorsque SELECT interroge l'une de nos bases de données. Veuillez voir la procédure simple et le code associé ci-dessous.ODP.Net Problèmes de performances des procédures stockées sur les jeux de données volumineux

Dans le code, la méthode ExecuteReader() s'exécute en 10 secondes environ sur une requête renvoyant 30K enregistrements. Itérer le lecteur prend 2 minutes (même si je ne pomperai pas les données dans un autre objet). 2 minutes pour un ensemble de données de 30k lignes sont inacceptables pour nous, car nous attendons des millions de données.

Y at-il quelque chose ici qui se démarque à l'un de vous? En espérant que votre expérience avec ODP.NET et PL/SQL pourrait aider.

create or replace PROCEDURE    TRACKING_FETCH (
       p_tracking_id    IN NUMBER, 
       p_parent_id    IN NUMBER, 
       p_media_id    IN NUMBER, 
       p_custodian_id   IN NUMBER, 
       p_return_cursor   OUT SYS_REFCURSOR) 
AS 
BEGIN 
    OPEN p_return_cursor FOR 
      SELECT 
        * 
      FROM 
        tracking 
      WHERE 
        (tracking_id = p_tracking_id OR p_tracking_id = 0) 
      AND (parent_id = p_parent_id OR p_parent_id = 0) 
      AND (media_id = p_media_id OR p_media_id = 0) 
      AND (custodian_id = p_custodian_id OR p_custodian_id = 0); 
END TRACKING_FETCH; 

-

using (DataFactory command 
     = new DataFactory(dbConnection, 
         DatabaseType.Oracle, 
         CommandType.StoredProcedure, 
         "TRACKING_FETCH")) 
{ 
     command.AddInParameter("p_tracking_id", DbType.Int32, trackingid); 
     command.AddInParameter("p_parent_id", DbType.Int32, parentid); 
     command.AddInParameter("p_media_id", DbType.Int32, mediaid); 
     command.AddInParameter("p_custodian_id", DbType.Int32, custodianid); 
     using (var dr = command.ExecuteReader()) 
     { 
       while (dr.Read()) 
       { 
        //Do Things... 
       } 
     } 
} 

sera grandement appréciée Toute orientation.

Répondre

4

Il est intéressant d'étudier l'interface d'attente Oracle. Je suppose que la latence du réseau vous tue. La procédure renvoie un pointeur sur le jeu de résultats. À un certain moment dans votre boucle, je suppose que vous allez chercher les lignes (même si elles sont en cours de dumping). Si vous vérifiez v $ sql, le nombre de récupérations effectuées et le nombre de lignes traitées sont corrigés. Divisez l'un par l'autre et vous verrez combien de lignes par fetch. Si vous faites 1 ligne/aller chercher ou même 10-20, c'est des milliers d'attentes réseau. Idéalement, vous voulez des milliers de lignes par extraction si vous voulez retirer des millions d'enregistrements, bien que cela puisse vous coûter en mémoire. En fonction de ce que vous faites avec ces millions de lignes, il peut être utile de repenser l'architecture. Par exemple, si elles sont sauvegardées dans un fichier, alors peut-être générer le fichier sur le serveur DB, le compresser, déplacer le fichier sur le réseau, puis le décompresser.

+1

Même si vous aviez raison au sujet de la latence qui nous tue, je n'ai pas réalisé que chaque lecture du lecteur de données était un aller-retour. Nous avons résolu ce problème en définissant le champ 'FetchSize' sur OracleDataReader, qui indique au lecteur le nombre de données à ramener à chaque aller-retour. Merci pour votre aide. – mattdlong

0

Avez-vous essayé d'exécuter un EXPLAIN PLAN sur la procédure stockée? Je ne vois pas de problèmes immédiats avec votre code ou votre procédure stockée, mais les analyses de table complètes tueraient sérieusement le temps d'exécution sur votre requête. Un plan d'explication vous indique s'il existe des analyses de table, puis vous pouvez affiner votre requête pour l'accélérer.

0

Ce n'est pas un problème de votre programme odp.net. La raison est dans le SELECT. Si la table contient beaucoup d'enregistrements, il se peut que l'optimiseur décide d'exécuter une analyse de table complète, en fonction de vos paramètres. Vérifiez avec explain plan comment l'instruction s'exécute. Si vous ne voyez rien d'utile. Essayez de trace l'instruction de voir les lectures physiques.

Questions connexes