Question

Nous avons des quelques problèmes de performances majeurs avec des requêtes SELECT sur une de nos bases de données. S'il vous plaît voir la procédure simple et code associé ci-dessous.

Dans le code de la méthode ExecuteReader () est exécuté en 10 secondes avec une requête de retour 30K enregistrements. Itérer Reader prend 2 minutes (même quand je ne suis pas pomper les données dans tout autre objet). 2 minutes pour un ensemble de données 30k ligne est inacceptable pour nous que nous attendons des jeux de données dans les millions.

Y at-il quelque chose ici qui se démarque à aucun de vous? En espérant que votre expérience avec ODP.NET et PL / SQL peut 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.

Était-ce utile?

La solution

étude sur Worth Oracle Wait Interface. Je ferais la latence du réseau suspect vous tue. La procédure renvoie un pointeur sur le jeu de résultats. À un certain moment dans votre boucle, je suppose que vous récupérez les lignes (même si elles sont l'objet de dumping).

v Checking $ sql vous dira combien de récupérations sont en cours et comment sont traitées de nombreuses lignes. Diviser un par l'autre et vous verrez le nombre de lignes par récupération. Si vous faites 1 ligne / chercher ou même 10-20, ce sont des milliers d'attente du réseau. Vous voulez idéalement des milliers de lignes par récupération si vous allez tirer de millions d'enregistrements, si cela peut vous coûter cher 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, alors peut-être générer si elles sont l'objet de dumping dans un fichier le fichier sur le serveur DB, zip, déplacez le fichier sur le réseau, puis décompressez-le.

Autres conseils

Avez-vous essayé l'exécution d'une EXPLAIN PLAN sur la procédure stockée? Je ne vois pas de problèmes immédiats avec soit votre code ou votre procédure stockée, mais analyses complètes de table tuerais sérieusement le temps d'exécution sur votre requête. Un plan d'expliquer vous dira s'il y a des analyses de table, et vous pouvez régler votre requête pour l'accélérer.

Il est pas un problème de votre programme odp.net. La raison en est dans le SELECT. Si la table contient beaucoup de dossiers, il peut être que l'optimiseur décide d'exécuter un scan de table, en fonction de vos paramètres. Renseignez-vous auprès rel="nofollow expliquer le plan comment la déclaration court. Si vous ne voyez rien utile. Essayez de tracer la déclaration voir les lectures physiques.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top