IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

SQLite : Problème de lenteur à l'écriture [Débutant]


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut SQLite : Problème de lenteur à l'écriture
    Bonjour à tous,
    J'ai une petite appli monoposte qui sauvegarde 5 ou 6 tables de datas dans un fichier de sauvegarde en utilisant SQLite.
    Mais la sauvegarde d'une petite centaines de lignes dans une table me prends dans les 10secondes environ. C'est pas dramatique en soit mais je me dit qu'il doit exister beaucoup mieux en terme de rapidité.
    J'ai pensé à SQL serveur CE qui est gratuit comme SQLite.

    Déjà j'espère que je ne fait pas un trop mauvais choix, mais vous pouvez toujours me proposer une autre BDD.

    Et je souhaiterais une classe ou quelques exemples de code qui comprends des fonctions de base comme :
    - Créer le fichier de base de données avec les tables (à partir du code)
    - Lire et écrire les datas (lignes par lignes).

    D'avance, merci beaucoup pour votre aide.

  2. #2
    Membre Expert Avatar de Thumb down
    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2019
    Messages
    1 592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juin 2019
    Messages : 1 592
    Par défaut
    Bonjour,
    Tu veux créer une nouvelle base SQLite ?
    Créer des tables à partir de Quoi ?

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut
    Bonjour, je me suis peut-être mal exprimé.
    SQLite me semble trop lent, et sauf erreur SQL serveur CE est plus rapide, plus performant donc j'aimerais changer carrément de SGBD (j'espère que c'est le bon terme).

    Par création de tables j'entends créer la structure de la base et les tables depuis le code car je suis habitué à faire comme cela et je ne voudrais pas changer.
    Ce sont des tables indépendantes sans aucune relations entre elle donc cela devrait être assez simple à faire je pense.

    Ces tables seront ensuite remplis avec des valeurs mais dans un second temps.

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    il faudrait se renseigner auprès d'autres personnes qui utilisent sqlite pour savoir si tes temps sont normaux ou si tu as mal codé

    sinon il y a sql server localDB qui est gratuit, il a les même limitations qu'sql express et les même performances aussi (enregistrer 100 lignes dans une table classique ne doit prendre que quelques dizaines de ms au plus)
    par contre c'est bien plus lourd qu'une simple dll à copier, il faut l'installer et ca prend quelques centaines de Mo (c'est le même moteur qu'sql server ...)

    sur sql server insérer les lignes une à une est souvent beaucoup plus lent qu'insérer toutes les lignes d'un coup (quitte à passer par une table temporaire)


    pour créer la structure :
    CREATE DATABASE ...
    CREATE TABLE ...
    CREATE FUNCTION ...

    pour les requetes types SELECT, si sqlite suit la norme sql tu ne devrais pas avoir trop de coder à modifier
    pour les petits projets il existe aussi Entity Framework qui s'occupe d'écrire les requetes à ta place et les classes correspondant aux tables (c'est un poil moins performant qu'écrire ses requetes soit même)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre Expert Avatar de Thumb down
    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2019
    Messages
    1 592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juin 2019
    Messages : 1 592
    Par défaut
    SQLite est une vrai base de données et en plus très performante au moins autant que SQL serveur !

    Notes qu'une fois que tu auras créer un base de données SQL serveur il te sera possible de créer des requêtes de création de table de SQLite vers SQL serveur directement via SQLite manager !

  6. #6
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut
    Merci Thumb down et Pol63 pour votre aide,
    Je joint l'extrait du code qui prends le plus de temps ainsi que l'affichage Debug.Print.
    Je n'ai copié qu'un petite partie : la première partie est relative à la création de tables, la 2eme partie est relative à l'écriture de chaque ligne.
    Comme on peux le voir l'écriture d'une line prends en moyenne 80ms, ce qui fait 8 secondes pour 100 lignes.

    Peut-être qu'il il y a mieux à faire avec SQLite mais je ne vois pas....
    Et j'ai trouvé une page de Benchmarks ci-dessous qui m'a orienté vers SQL serveur CE :
    https://www.codeproject.com/Articles...dded-DB-for-Ne

    Aussi je ne souhaite pas que le SGBD soit trop lourd ou qui s'installe comme semble l'indiquer Pol63. Avec SQLite j'ai juste 2 petites dll à copier dans le dossier du programme et c'est tout.
    Merci pour votre avis...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
         Public Function ExecuteNonQuery(sql As String) As Integer
                Dim cnn As New SQLiteConnection(dbConnection)
                cnn.Open()
                Dim mycommand As New SQLiteCommand(cnn)
                mycommand.CommandText = sql
                Dim Chrono1 As New Stopwatch
                Chrono1.Start()
                Dim rowsUpdated As Integer = mycommand.ExecuteNonQuery()
                Chrono1.Stop()
                Debug.Print(String.Format("Chrono (ExecuteNonQuery) : {0}ms | {1}", Chrono1.Elapsed.TotalMilliseconds, sql))
                cnn.Close()
                mycommand.Dispose()
                Return rowsUpdated
            End Function
    Chrono (ExecuteNonQuery) : 221,7132ms | CREATE TABLE Noeuds(
    Id INTEGER,
    Text1 TEXT,
    Text2 TEXT);
    Chrono (ExecuteNonQuery) : 79,9005ms | CREATE TABLE Segments(
    Repere TEXT,
    Id1 INTEGER,
    Id2 INTEGER,
    Longueur REAL);
    Chrono (ExecuteNonQuery) : 82,0166ms | CREATE TABLE Liaisons(
    Repere TEXT,
    Id1 INTEGER,
    Id2 INTEGER,
    RouteN TEXT,
    RouteS TEXT,
    Distance REAL,
    TenantText1 TEXT,
    TenantText2 TEXT,
    AboutText1 TEXT,
    AboutText2 TEXT,
    Section REAL,
    Poids REAL);
    Chrono (ExecuteNonQuery) : 81,4584ms | CREATE TABLE Cables(
    Repere TEXT,
    LiaisonRepere TEXT,
    LiaisonDistance REAL,
    Serie TEXT,
    Designation TEXT,
    Marque TEXT,
    Reference TEXT,
    Hauteur REAL,
    Largeur REAL,
    Diametre REAL,
    Section REAL,
    Poids REAL,
    LongueurT REAL,
    NoeudTenantText1 TEXT,
    NoeudTenantText2 TEXT,
    LiaisonTenantText1 TEXT,
    LiaisonTenantText2 TEXT,
    TenantText1 TEXT,
    TenantText2 TEXT,
    NoeudAboutText1 TEXT,
    NoeudAboutText2 TEXT,
    LiaisonAboutText1 TEXT,
    LiaisonAboutText2 TEXT,
    AboutText1 TEXT,
    AboutText2 TEXT);
    Chrono (ExecuteNonQuery) : 80,9655ms | CREATE TABLE Canalisations(
    Repere TEXT,
    SegmentRepere TEXT,
    Liaisons TEXT,
    NbLiaisons INTEGER,
    LiaisonsPosées TEXT,
    NbLiaisonsPosées INTEGER,
    Section REAL,
    Poids REAL);
    Chrono (ExecuteNonQuery) : 79,6542ms | insert into Cables( Repere, LiaisonRepere, LiaisonDistance, Serie, Designation, Marque, Reference, Hauteur, Largeur, Diametre, Section, Poids, LongueurT, NoeudTenantText1, NoeudTenantText2, LiaisonTenantText1, LiaisonTenantText2, TenantText1, TenantText2, NoeudAboutText1, NoeudAboutText2, LiaisonAboutText1, LiaisonAboutText2, AboutText1, AboutText2) values( 'W101', '', '0', '', '', '/', '/', '0', '0', '0', '0', '0', '0', '', '', '', '', 'Alim caméra 1', 'P1001', '', '', '', '', 'Alim caméra GOI 1', 'P12042');
    Chrono (ExecuteNonQuery) : 81,3026ms | insert into Cables( Repere, LiaisonRepere, LiaisonDistance, Serie, Designation, Marque, Reference, Hauteur, Largeur, Diametre, Section, Poids, LongueurT, NoeudTenantText1, NoeudTenantText2, LiaisonTenantText1, LiaisonTenantText2, TenantText1, TenantText2, NoeudAboutText1, NoeudAboutText2, LiaisonAboutText1, LiaisonAboutText2, AboutText1, AboutText2) values( 'W102', '', '0', '', '', '/', '/', '0', '0', '0', '0', '0', '0', '', '', '', '', 'Alim Obturateur 1', 'P1002', '', '', '', '', 'Alim obturateur GOI 1', 'P12043');
    Chrono (ExecuteNonQuery) : 81,4953ms | insert into Cables( Repere, LiaisonRepere, LiaisonDistance, Serie, Designation, Marque, Reference, Hauteur, Largeur, Diametre, Section, Poids, LongueurT, NoeudTenantText1, NoeudTenantText2, LiaisonTenantText1, LiaisonTenantText2, TenantText1, TenantText2, NoeudAboutText1, NoeudAboutText2, LiaisonAboutText1, LiaisonAboutText2, AboutText1, AboutText2) values( 'W103', '', '0', '', '', '/', '/', '0', '0', '0', '0', '0', '0', '', '', '', '', 'Alim caméra 2', 'P1003', '', '', '', '', 'Alim caméra GOI 2', 'P12044');
    Chrono (ExecuteNonQuery) : 81,184ms | insert into Cables( Repere, LiaisonRepere, LiaisonDistance, Serie, Designation, Marque, Reference, Hauteur, Largeur, Diametre, Section, Poids, LongueurT, NoeudTenantText1, NoeudTenantText2, LiaisonTenantText1, LiaisonTenantText2, TenantText1, TenantText2, NoeudAboutText1, NoeudAboutText2, LiaisonAboutText1, LiaisonAboutText2, AboutText1, AboutText2) values( 'W104', '', '0', '', '', '', '/', '0', '0', '0', '0', '0', '0', '', '', '', '', 'Alim obturateur 2', 'P1004', '', '', '', '', 'Alim obturateur GOI 2', 'P12045');
    Chrono (ExecuteNonQuery) : 81,9278ms | insert into Cables( Repere, LiaisonRepere, LiaisonDistance, Serie, Designation, Marque, Reference, Hauteur, Largeur, Diametre, Section, Poids, LongueurT, NoeudTenantText1, NoeudTenantText2, LiaisonTenantText1, LiaisonTenantText2, TenantText1, TenantText2, NoeudAboutText1, NoeudAboutText2, LiaisonAboutText1, LiaisonAboutText2, AboutText1, AboutText2) values( 'W105', '', '0', '', 'SABIX A226 FRNC C1 3G1,5', 'AUXICOM', '62260315', '0', '0', '0', '0', '0', '7.8', '', '', '', '', 'Secteur', 'P1005', '', '', '', '', 'PDU 1_Out_230V', 'P2019');
    Chrono (ExecuteNonQuery) : 81,3202ms | insert into Cables( Repere, LiaisonRepere, LiaisonDistance, Serie, Designation, Marque, Reference, Hauteur, Largeur, Diametre, Section, Poids, LongueurT, NoeudTenantText1, NoeudTenantText2, LiaisonTenantText1, LiaisonTenantText2, TenantText1, TenantText2, NoeudAboutText1, NoeudAboutText2, LiaisonAboutText1, LiaisonAboutText2, AboutText1, AboutText2) values( 'W106', '', '0', '', 'Cordon 4P CAT6A Gris 7ml', 'DRAKA HOLDING', '21.05.9570', '0', '0', '0', '0', '0', '6.85', '', '', '', '', 'Ethenet IP 1', 'P1006', '', '', '', '', 'SWT1_IP', 'P9030');
    Chrono (ExecuteNonQuery) : 81,2227ms | insert into Cables( Repere, LiaisonRepere, LiaisonDistance, Serie, Designation, Marque, Reference, Hauteur, Largeur, Diametre, Section, Poids, LongueurT, NoeudTenantText1, NoeudTenantText2, LiaisonTenantText1, LiaisonTenantText2, TenantText1, TenantText2, NoeudAboutText1, NoeudAboutText2, LiaisonAboutText1, LiaisonAboutText2, AboutText1, AboutText2) values( 'W107', '', '0', '', '', '/', '/', '0', '0', '0', '0', '0', '0', '', '', '', '', 'Alim COE caméra 1', 'P1007', '', '', '', '', 'COE caméra GOI 1', 'P12046');

  7. #7
    Membre Expert Avatar de Thumb down
    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2019
    Messages
    1 592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juin 2019
    Messages : 1 592
    Par défaut
    si tu travail de la même façon avec Sql Serveur tu auras le même problème!
    chaque fois que tu exécuter une requête tu fais un accès disque il faut limiter tes requêtes! en réalité tu pourrais en faire qu'une!

    tu peux créer toutes tes table!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    sql="CREATE TABLE Noeuds(Id INTEGER,
    Text1 TEXT,
    Text2 TEXT)
    
    
     CREATE TABLE Segments(
    Repere TEXT,
    Id1 INTEGER,
    Id2 INTEGER,
    Longueur REAL)"
    
    Chrono (Sql) 
    ajoutes toute tes values(), values(),values() pour tous tes insert
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    sql="insert into Cables( Repere, LiaisonRepere, LiaisonDistance, Serie, Designation, Marque, Reference, Hauteur, Largeur, Diametre, Section, Poids, LongueurT, NoeudTenantText1, NoeudTenantText2, LiaisonTenantText1, LiaisonTenantText2, TenantText1, TenantText2, NoeudAboutText1, NoeudAboutText2, LiaisonAboutText1, LiaisonAboutText2, AboutText1, AboutText2) 
    values( 'W101', '', '0', '', '', '/', '/', '0', '0', '0', '0', '0', '0', '', '', '', '', 'Alim caméra 1', 'P1001', '', '', '', '', 'Alim caméra GOI 1', 'P12042')
     ,values( 'W102', '', '0', '', '', '/', '/', '0', '0', '0', '0', '0', '0', '', '', '', '', 'Alim Obturateur 1', 'P1002', '', '', '', '', 'Alim obturateur GOI 1', 'P12043');"
    
    Chrono (Sql) 

  8. #8
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut
    Merci Thumb down,

    En effet je ne savais pas que l'on pouvait faire qu'une seule requête, mais du coup ca fait une sacrée ligne de commande ! Est ce que la limite en nombre de caractères est connue pour cette ligne de commande ?

    J'y connais pad grand chose en SGBD mais il existe pas un mécanisme propre au SGBD pour stoker dans une sorte de tampon toute les commandes et les exécuter à la fin ?

    A une époque j'avais travaillé avec des transactions sous Access, est ce que ca existe sous SQLite et surtout est ce que ca pourrait faire l'affaire ?

    Désolé si j'ai l'air de mélanger un peu tout mais j'explore des pistes et je souhaite faire le bon choix avant de toucher une ligne de code

  9. #9
    Membre Expert Avatar de Thumb down
    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2019
    Messages
    1 592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juin 2019
    Messages : 1 592
    Par défaut
    Déjà tu peux faire une requête pour la création de tes tables et une par insert table avec tous les values.

    Pendant plus de 20 ans j'ai fais de requêtage sur tout ce qui ressemble à une base de données, mais toi tu découvres c'est normal de patogé un peut!

    Mantenant SQL serveur express est gratuit, si demain tu prends ton essor tu pourras passer à un licence payante sans devoir refaire ton code !

    Pour le choix SQL serveur est lourd à mettre en œuvre mais te permet de grandir !

    SQLite est puissant et lègé !

  10. #10
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    concernant le fait de ne faire qu'une requete, en théorie oui, en pratique non
    concaténer les valeurs dans la requete est une faute la plupart du temps, cela amène des problèmes de sécurité tels que l'injection sql, ou des bugs (tel que les formats des dates et la gestion des ')
    aussi on préfère utiliser les DbParameters, et là faire x requetes en une fois devient peu pratique voir impossible
    là vu que c'est un commandtext qui est passé à ta méthode, ca doit être néanmoins faisable, même si peu conseillé

    par contre ce qui ralenti je pense, c'est d'ouvrir la connexion et de la fermer à chaque fois
    s'il y a 50 requetes à faire à la suite il faut garder la connexion ouverte, ouvrir une connection peut prendre du temps (au moins sur certains sgbd)
    pour ca, soit tu passes un list(of sql) et faire un for each => executenonquery
    soit passer la connection à la méthode en plus du sql (et idéalement un list(of dbparameter) ^^)

    sur les sgbd avec gestion du verrouillage et journalisation des modifications le mieux reste de faire les insert un par un dans une table temporaire, puis de faire insert into table select * from #tabletemp, c'est ce qu'il y a de plus rapide

    une transaction sert à garantir l'intégrité d'un bloc de requete, par exemple si tu dois retirer un truc dans une table et en ajouter un autre dans une autre, mais que tu veux que ca soit tout ou rien une transaction devient utile
    le sgbdr annulera la 1ère requete si la 2ème plante
    ca peut etre utile aussi pour s'assurer que les 50 insert passent tous ou aucun
    à priori ca existe sur sqlite ...

    la limite de la taille d'un commandtext doit être de 2Go ^^
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  11. #11
    Membre émérite
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Octobre 2006
    Messages
    741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Octobre 2006
    Messages : 741
    Par défaut
    Je confirme ce que Pol63 a écrit, SQLite n'est pas en cause.
    Beaucoup de monde l'utilise, et il marche très bien.
    Sans le savoir, ceux qui ont des Mac, qui utilisent leur smartphone qu'il soit sous iOS ou Android, qui surfent avec Firefox l'utilisent tous les jours. Quand tu utilises les outils d'Adobe aussi, quand tu conduis ta voiture si elle est récente, etc...

    La connexion, la définition de l'objet SQLiteCommand, ne devraient être faits qu'une fois.
    Idéalement, tu gères aussi la reconnexion en cas de perte de liaison, mais bon on va pas compliquer ici...
    Modifie légèrement ton code pour que seuls le remplissage de la commande et son exécution soient dans la boucle et tu vas voir que çà ira bien plus vite.

    Une petite question tout de même.
    Ton serveur est local ou distant ?

  12. #12
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut
    Bonjour à tous,
    Voici mon retour après quelques essais sur une BDD complète qui mets 34 secondes pour s'enregistrer.

    J'ai d'abord exploré la piste de Pol63 qui me semblé la bonne car effectivement j'ouvrais et je fermais la connexion lors de l'écriture de chaque ligne.
    Une fois cette première correction effectuée, la durée totale de sauvegarde est passé à 32 secondes. J'aurais pensé gagner davantage mais bon....c'est toujours ca de gagné.

    Ensuite j'ai encapsulé tout ca dans une transaction et là...stupéfaction.....je suis passé à 0.8 secondes.....la par contre je ne pensais pas gagner autant car je me disais que ce n'était pas la fonction première d'une transaction.

    Bilan : je suis extremement satisfait par le résultat, en plus d'avoir "sécurisé" l'écriture de ma BDD.

    Je remercie vraiment tous le monde pour votre participation. Je suis vraiment très satisfait. Je garde SQLite LOL.

    PS : j'ai changé le titre du sujet pour que tous le monde puisse s'y retrouver.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 17/07/2008, 15h15
  2. Réponses: 8
    Dernier message: 18/07/2007, 16h41
  3. Réponses: 2
    Dernier message: 09/07/2007, 15h45
  4. [Système] Alternative à PHP pour les uploads HTTP
    Par superjun dans le forum Langage
    Réponses: 2
    Dernier message: 08/07/2006, 00h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo