2010-12-06 11 views
1

J'ai une tonne de journaux SQL dont je veux extraire des données. Cette tâche prend beaucoup de temps car je regroupe plusieurs colonnes. Ainsi, j'ai décidé d'extraire les journaux avec les colonnes que je regrouperais généralement sans faire de GROUP BY du côté SQL. Au lieu de cela, je veux utiliser Perl pour faire mon regroupement par. Lors de l'utilisation de Perl, la solution à laquelle je pense est de créer un hachage n-dimensionnel à regrouper sur les différentes colonnes. Existe-t-il des utilitaires de ligne de commande ou des fonctions Perl qui me permettront de faire la même chose?GROUP BY utilisant Perl

+3

Il ne va probablement pas être plus vite que de laisser votre base de données ne le regroupement. Vous devriez plutôt chercher à optimiser cette requête. – Ether

+0

Juste par curiosité ... qu'est-ce qui vous a amené à croire que vous avez un problème avec le groupe? – Ronnis

Répondre

2
  1. Comme l'a dit Ether dans le commentaire, laissez l'outil qui a été réellement conçu et optimisé pour le travail faire le travail. Un serveur de base de données exécutant correctement une requête optimisée est TRES peu susceptible d'être plus lent que vous ne pouvez le faire en dehors de la base de données. Entre autres choses, vous gaspillerez des ressources en transmettant plus de données sur le réseau et aurez besoin de plus de mémoire. Comme une des optimisations, essayez d'utiliser une table temporaire, mais sans avoir un schéma complet, une requête et un moteur de base de données, je ne me risquerais pas à donner des conseils d'optimisation spécifiques. L'approche de l'extérieur de DB peut parfois être meilleure, par exemple s'il y a TRÈS TRÈS peu de lignes qui ont des clés "groupées par" en double, dans ce cas il n'y a pas beaucoup d'économies en termes de ressources pour transmettre les données groupées ; ET quand votre logique sur le côté Perl aurait nécessité de stocker chaque rangée dans la mémoire de toute façon au lieu d'itéter sur eux et de jeter les itératifs loin. Si vous voulez toujours essayer de faire cela en Perl, une bonne approche consiste à faire un hachage de niveau SINGLE, et de développer un moyen peu coûteux d'encoder les valeurs dans vos colonnes clés uniques en une seule valeur de hachage (pack/décompresser peut être utilisé dans certaines circonstances, ou fractionner/rejoindre, ou plus spécifique à une situation, mais de manière plus performante). La seule exigence est que la valeur codée puisse être mappée de manière unique vers les valeurs de colonne de clé uniques.

    # Store 
    my %storage; 
    foreach my $row (@$result_set) { 
        my $hash_key = encode_hash_key(row); 
        my $new_row = $row; 
        if (exists $storage{$hash_key}) { 
         $new_row = merge_rows($row, $storage{$hash_key}); 
        } 
        $storage{$hash_key} = $new_row; 
    } 
    
+0

Un bon moyen, bon marché, est d'utiliser l'ancienne émulation multidimensionnelle de Perl (voir perldoc -v "$;"), donc quelque chose comme: $ storage {$ row -> {field1}, $ row -> {field2}, $ row -> {field3}} = merge_row ($ stockage {ligne -> {champ1}, $ ligne -> {champ2}, $ ligne -> {champ3}}, $ ligne); – MkV

+0

ou faites simplement encode_hash_key rejoindre ($ ;, @ $ row {@group_by_fields}) – MkV

+0

@MKV - l'inconvénient de joindre les clés en tant qu'encodage est le coût du décodage via split, ainsi que les complexités concomitantes lorsque les valeurs peuvent contenir des virgules. Cela PEUT être l'une des méthodes, mais dans certaines (ou plusieurs) situations pas la plus performante si vous vous souciez du décodage. – DVK