2010-04-01 11 views
2

J'utilise sql plus pour exécuter une requête (un select) et vider le résultat dans un fichier, en utilisant l'option spool. J'ai environ 14 millions de lignes, et il faut environ 12 minutes pour faire la décharge. Je me demandais s'il y avait quelque chose pour rendre la décharge plus rapide?oracle sql plus spool

Ci-dessous mon sql ainsi que des options:

whenever sqlerror exit sql.sqlcode 
     set pagesize 0 
     set linesize 410 
     SET trimspool ON 
     set heading on 
     set feedback off 
     set echo off 
     set termout off 
     spool file_to_dump_into.txt 
     select * from mytable; 

Merci.

+0

Quelques bons conseils pour utiliser sql * plus ici, mais je dois demander: pourquoi bobiner autant par sql * plus? Créez une application simple pour le faire pour vous, puis vous aurez plus de contrôle sur la sortie, et il sera facile de réutiliser ou de modifier pour d'autres requêtes. Just sayin ' – nothingisnecessary

Répondre

1

Avec une requête typique, 14M enregistrements est au moins plusieurs centaines de mégaoctets de données à extraire du serveur, passer à travers la connexion et enregistrer sur le disque. Étant donné cela, 12 minutes ne me semble pas trop.

Cependant, il est toujours possible que votre requête puisse être optimisée. Pourriez-vous s'il vous plaît le poster ici?

+0

La requête est optimisée, j'ai travaillé dessus pour la rendre plus rapide. Donc, ce qui reste est la décharge. Le fichier a environ 400 Mo. Je pense à quelque chose comme la taille du tampon de la décharge, mais je ne sais pas s'il existe une telle option. –

+0

La requête elle-même prend 1,5 minute, et le reste c'est le vidage. –

+0

Utilisation du navigateur de session de cueillette Je peux voir le temps qu'il faut pour faire la requête et le temps qu'il faut pour faire la sauvegarde. –

1

Est-ce que cela se passe sur le réseau ou êtes-vous connecté à la boîte qui a la base de données? Si vous avez accès, peut-être vous pouvez exécuter votre session sqlplus sur la boîte où vit la base de données et compresser le fichier puis envoyer le fichier à votre machine locale. Il pourrait être plus rapide d'envoyer un gros fichier sur le fil au lieu d'envoyer des millions de dossiers plus petits. Bien sûr, cela ne le rendra pas super rapide, mais pourrait raser un peu de temps.

Aussi avec autant de données avez-vous vraiment besoin de le spouler dans un fichier? Pouvez-vous faire une exportation à la place?

+0

Bonne question. En fait, j'ai besoin de faire une bobine parce que la sélection n'est pas un choix simple. Je fais un petit traitement sur une valeur de champ basée sur la valeur précédente de ce champ. À la fin, je génère un fichier formaté (pas seulement les colonnes). Donc, c'est un peu la bobine obligatoire. Je fais mon test sur une machine de test. Je vais demander à voir si dans l'environnement de production le serveur unix est sur la même machine que le serveur Oracle. –

0

Vous pouvez activer en mémoire tampon de sortie en ajoutant à vous scriptez

SET FLUSH OFF 

Mais le résultat dépend de votre système d'exploitation.

+0

Oui, je l'ai juste essayé, mais le même résultat. Merci quand même. –

2

Vous pourriez trouver plus rapide d'utiliser UTL_FILE, mais probablement pas beaucoup plus vite. Dans mon test, il était légèrement plus rapide sur environ 20k de rangs, mais cela dépasse les 14 millions et cela en vaut peut-être la peine.

Je crois que si vous voulez obtenir plus rapidement que cela, le chemin à parcourir serait pro * c .. mais je ne suis pas entré dans cela, donc je ne peux pas vraiment le conseiller.

set pagesize 1000 
set FLUSH OFF 
drop user usera cascade; 
create user usera default tablespace users identified by abc123; 
grant create session to usera; 
grant resource to usera; 

create or replace directory testdir as '/tmp'; 
grant read,write on directory testdir to usera; 
grant execute on UTL_FILE to usera; 

connect usera/abc123; 

set timing on 

spool /tmp/spooltest.txt 
select object_name from all_objects; 
spool off 

DECLARE 
v_file UTL_FILE.FILE_TYPE; 
TYPE t_col is table of all_objects.object_name%type index by PLS_INTEGER; 
v_object_names t_col; 

BEGIN 
    v_file := UTL_FILE.FOPEN('TESTDIR','utlfiletext.txt','w'); 

    select object_name BULK COLLECT INTO v_object_names 
    from all_objects; 

    for idx IN 1 .. v_object_names.COUNT LOOP 
    UTL_FILE.PUT_LINE(v_file, v_object_names(idx), FALSE); 
    END LOOP; 

    UTL_FILE.FCLOSE(v_file); 
END; 
/

Les résultats. Le meilleur résultat étant de sqlplus seulement, le fond en utilisant UTL_FILE

23931 rows selected. 

Elapsed: 00:00:06.60 

PL/SQL procedure successfully completed. 

Elapsed: 00:00:05.45 
0

Lors de l'obtention d'un grand nombre de résultats d'une requête dans SQL * Plus, j'ai trouvé qu'une chose qui prend beaucoup de temps est l'affichage réel des données. Si vous spoulez les données dans un fichier, vous pouvez SET TERMOUT OFF et la requête s'exécute beaucoup plus rapidement car elle n'a pas besoin de passer le temps pour l'écrire à l'écran.

+0

Oh, tant pis. J'ai relu votre message, et je vois maintenant que vous l'avez déjà dans vos paramètres. – AndyDan

6

Êtes-vous concaténant & pour délimiter vos colonnes ou exportez-vous à largeur fixe?

Voir cette documentation au SQL*Plus Script Tuning. Spécifique à votre script, voici quelques façons possibles de l'accélérer:

  1. Assurez-vous que LINESIZE est aussi petit que possible. Ajoutez vos longueurs de colonne max (plus les délimiteurs si pas de largeur fixe).Cela peut avoir un effet dramatique sur les performances, car SQL * Plus alloue cette quantité de mémoire pour chaque ligne exportée. 410 n'est pas si grand, mais si vous pouvez le diminuer cela aiderait. Cela a fait une grande différence, selon mon expérience.
  2. Ne pas activer TRIMSPOOL. Cela peut aussi avoir un grand impact. Chaque ligne sera ensuite complétée à LINESIZE, mais avec une taille de ligne optimale, et selon la façon dont vous utilisez le fichier, cela peut être acceptable. Cependant, si vous voulez éliminer complètement les espaces de fin, il est souvent plus rapide de les découper en utilisant d'autres méthodes après l'exportation.
  3. Jouez avec ARRAYSIZE. Cela peut aider (un peu). Il définit la taille d'extraction pour SQL * Plus. La valeur par défaut est 15 lignes. Cumuler à, disons, 100 peut aider, mais aller trop grand pourrait diminuer la vitesse.

Espérons que cela aide!

+0

'arraysize' est le grand ici. D'après mon expérience, cela peut faire une énorme différence - je m'attendrais à une amélioration de l'ordre de grandeur pour un ensemble de résultats de 14 millions de lignes. Je vais devoir essayer la chose no-trimspool. –

+0

Le lien est mort maintenant. Je pense que c'est la même page: [SQL plus de réglage de script] (http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch8.htm) (URL Juillet 2016) –

0

Certaines options sont disponibles auprès de Tom Kyte, qui est un vrai gourou.