[SQL] Performance et Index

11laurent11 Messages postés 31 Statut Membre -  
 didou -
Bonjour,

J'ai une base de données qui contient pour l'instant environ 150 000 entrées qui sont en fait des numéros de téléphone avec un certain nombres de champs liés à ces numéros de téléphone.

numero_telephone | champ1 | champ2 | ... => Tous en VARCHAR

Quand je veux alimenter la base de données avec des nouveaux numéros (variable $numero_a_verifier) de téléphone, je dois bien sûr vérifier que ces numéros n'existent pas déjà et c'est là que les problèmes commencent...

Je fais donc un SELECT num_telephone where num_telephone=$numero_a_verifier

Ca fonctionne mais c'est terriblement lent et comme j'alimente la base avec des paquets de plus de 100 000 numéros, SQL doit aller vérifier les 150 000 existants et ça prend un temps dingue (plusieurs heures!)

Je pense donc que j'ai mal formatté ma base. Je dois probablement indexer la base, j'ai simplement cliqué sur l'icone index de la colonne numero_telephone mais c'est à peine un peu plus rapide.

Est-ce que quelqu'un peut m'expliquer comment je peux optimiser ce genre de requêtes ?

Merci !
Laurent
A voir également:

9 réponses

ranjok Messages postés 337 Statut Membre 35
 
>Pourquoi ne pas créer une table dont la clé primaire est le numero de téléphone ?

C'est ridicule !!!
Ajoute une contrainte UNIQUE au champ qui contient les numéros de téléphone, ainsi aucune nécessité de vérifier si ça existe déja

Ou bien utiliser un INDEX sur ce champ est aussi une solution, ça prend juste plus de mémoire !!!
2
sapatera
 
Bonjour,

Pourquoi ne pas créer une table dont la clé primaire est le numero de téléphone ?
0
blux Messages postés 27887 Date d'inscription   Statut Modérateur Dernière intervention   3 361
 
Salut,

pourquoi tester s'il existe déjà ?

Tu l'insères et ton SGBD va refuser l'insertion s'il existe déjà ...à condition que le numéro de téléphone soit la clé primaire...
0
Laurent
 
Merci pour vos réponses!

J'ai essayé la clé primaire et je trouve ça encore trop lent :(

Blux: est-ce que le fait d'utiliser une clé primaire transforme une requête insert into en update? Le problème avec ma vérification c'est que pour chaque fichier que je charge, je dois éviter d'insérer un numéro qui existe déjà mais en plus si le numéro existe déjà, je dois faire une mise à jour des autres champs liés à ce numéro dans la base de données.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
blux Messages postés 27887 Date d'inscription   Statut Modérateur Dernière intervention   3 361
 
Le clé primaire est sûrement le truc le plus rapide pour accéder à un enregistrement...

Si ça ne va pas assez vite pour toi, change de SGBD ou d'ordinateur...

Le fait d'utiliser une clé primaire ne fait en aucun cas de mise à jour, seul le texte de la requête le permet : INSERT ou UPDATE...
0
dja7 Messages postés 1 Statut Membre
 
Salut,
Je realise exactement le meme projet que toi, et j'ai le meme probleme : tant qu'on ne fait qu'inserer c'est rapide, mais dés qu'on rajoute autre chose dans la boucle ça devient trop lent.
As tu trouvé une solution depuis?

Et pour l'idée de Blux, comment effectuer un update si le insert echoue? Ainsi?

mysql_query("INSERT INTO table (num)
VALUES( '$num')",$connex)
or die ("UPDATE table SET nbr = nbr+1 WHERE num ='$num'");

Merci
0
xo
 
Bonjour,

lancez d'abord un count(*) : ( SELECT count(*) from table where num_telephone='$numero_a_verifier' )

si ça renvoie >0 , pas d'insert sinon insert

faire un count meme sur une tres grosse table est tres rapide.
0
Thibaut
 
Pourquoi ne pas séparer cela en 2 étapes ?

Dans une première boucle effectuer toutes les vérifications nécessaires, puis dans une 2eme boucle effectuer les insertions.

De cette façon on évite que les mises à jour des index dues aux insertions se fassent à chaque tour de boucle...

Je ne suis pas expert en BDD mais j'essayerais ça.

Bonne chance.
0
didou
 
BONJOUR,

il faut utiliser une procédure PLSQL, et désactive les contrainte de clé primaire et étrangère .
C'est le contrôle qui prend du temps.
0