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

PHP & Base de données Discussion :

Optimisation Script PHP


Sujet :

PHP & Base de données

  1. #1
    Membre actif Avatar de JmL40
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 348
    Points : 246
    Points
    246
    Par défaut Optimisation Script PHP
    Bonjour,

    Je sollicite votre aide dans le cadre d'une réflexion sur un algorithme (script PHP).

    J'ai une TABLE (Microsoft SQL Server 2008) "IDENTITE" constituée des colonnes suivantes :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE [IDENTITE](
    	[IDI_ID] [int] IDENTITY(1,1) NOT NULL,   [PK]
    	[IDI_F1] [varchar] NULL,
    	[IDI_F2] [varchar](25) NULL,
    	[IDI_M1] [varchar](25) NULL,
    	[IDI_M2] [varchar](25) NULL,
    	[IDI_FORMULA] [varchar](25) NULL,
    	[IDI_NAME] [varchar](25) NULL
    )

    La colonne "IDI_ID" est l'identifiant unique de la table (identity).

    Les colonnes "IDI_F1", "IDI_F2", "IDI_M1", "IDI_M1" sont les parents potentiels de mon identifiant.

    La colonne "IDI_FORMULA" est la combinaison des colonnes parents : IDI_F1.IDI_F2/IDI_M1.IDI_M2 ou IDI_F2.IDI_F1/IDI_M2.IDI_M1

    La colonne "IDI_NAME" est un nom commun que l'on attribut à mon identifiant.

    Objectif :

    L'objectif du script est de rechercher si les parents passés en paramètres de mon script existe dans la table "IDENTITE", sachant qu'il faut tester toutes les combinaisons possibles, soit 8 avec au minimum deux parents et au maximum 4 parents.

    Exemple :

    Dans la table, j'ai la ligne suivante :

    IDI_ID : 		198587
    IDI_F1 :		TITI
    IDI_F2 :		TUTU
    IDI_M1 :		TOTO
    IDI_M2 :		TKTK
    IDI_FORMULA :	TITI.TUTU/TOTO.TKTK
    IDI_NAME	:	JML
    Je veux donc rechercher cette ligne mais les paramètres passés sont :

    IDI_F1 :		TUTU
    IDI_F2 :		TITI
    IDI_M1 :		TKTK
    IDI_M2 :		TOTO
    IDI_FORMULA :	TUTU.TITI/TKTK.TOTO
    La formule est inversée donc je ne trouverai jamais ma ligne et pourtant elle existe bien.

    Je pensais donc pour un paramètre, tester 8 requêtes avec des wheres représentants les 8 combinaisons possibles ou sinon faire un where avec les 8 combinaisons imbriquées par un OR.

    Sachant que la table fait environ 800 000 lignes et que la recherche peut contenir 1000 formules à identifier ... Je souhaiterai un peu de votre aide !

    Si vous voulez plus de précisions, je me tiens à votre disposition.

    Cordialement
    while (true) echo 'comique';
    Du comique de répétition ...
    Pour des questions de lisibilité, utilisez la balise [code]
    Si votre problème est résolu, n'oubliez pas le tag

  2. #2
    Membre expérimenté
    Avatar de ryan
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2003
    Messages
    956
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2003
    Messages : 956
    Points : 1 316
    Points
    1 316
    Billets dans le blog
    1
    Par défaut
    Hola,

    Si j'ai bien compris ton problème (mais rien n'est moins sur) , quelque chose du genre devrait aider:

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM IDENTITE WHERE IDI_FORMULA LIKE '%TITI%' AND IDI_FORMULA LIKE '%TUTU%' AND IDI_FORMULA LIKE '%TKTK%' AND IDI_FORMULA LIKE '%TOTO%'

    Ryan
    Un ascenseur est une machine qui passe quand même la moitié de son temps à descendre.

  3. #3
    Membre actif Avatar de JmL40
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 348
    Points : 246
    Points
    246
    Par défaut
    Bonjour,

    En fait, l'utilisateur va passer en paramètre une liste de parents soit F1, F2, M1, M2 correspondant à une formule F1.F2/M1.M2. Les parents peuvent être saisi dans un ordre différent que celui référencé dans la table IDENTITE.

    Par exemple dans la table, je peux avoir dans la table F2.F1/M2.M1 et l'utilisateur tente de rechercher F1.F2/M1.M2.

    Idée 1 :

    Je pense donc parcourir l'ensemble des formules à rechercher et composer un ensemble de requêtes comme cela (pour chaque formule à rechercher), si un numéro existe je le retourne :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT * FROM IDENTITE WHERE IDI_F1 = 'TUTU' AND IDI_F2 = 'TITI' AND IDI_M1 = 'TOTO' AND IDI_M2 = 'TKTK'
    SELECT * FROM IDENTITE WHERE IDI_F1 = 'TUTU' AND IDI_F2 = 'TITI' AND IDI_M1 = 'TKTK' AND IDI_M2 = 'TOTO'
    SELECT * FROM IDENTITE WHERE IDI_F1 = 'TITI' AND IDI_F2 = 'TUTU' AND IDI_M1 = 'TKTK' AND IDI_M2 = 'TOTO'
    SELECT * FROM IDENTITE WHERE IDI_F1 = 'TITI' AND IDI_F2 = 'TUTU' AND IDI_M1 = 'TOTO' AND IDI_M2 = 'TKTK'
    SELECT * FROM IDENTITE WHERE IDI_F1 = 'TOTO' AND IDI_F2 = 'TKTK' AND IDI_M1 = 'TUTU' AND IDI_M2 = 'TITI'
    SELECT * FROM IDENTITE WHERE IDI_F1 = 'TOTO' AND IDI_F2 = 'TKTK' AND IDI_M1 = 'TITI' AND IDI_M2 = 'TUTU'
    SELECT * FROM IDENTITE WHERE IDI_F1 = 'TKTK' AND IDI_F2 = 'TOTO' AND IDI_M1 = 'TUTU' AND IDI_M2 = 'TITI'
    SELECT * FROM IDENTITE WHERE IDI_F1 = 'TKTK' AND IDI_F2 = 'TOTO' AND IDI_M1 = 'TITI' AND IDI_M2 = 'TUTU'

    Idée 2 :

    Je pense exécuter une seule requête avec un WHERE contenant toutes les combinaisons :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT * FROM IDENTITE WHERE
    (IDI_F1 = 'TUTU' AND IDI_F2 = 'TITI' AND IDI_M1 = 'TOTO' AND IDI_M2 = 'TKTK') OR
    (IDI_F1 = 'TUTU' AND IDI_F2 = 'TITI' AND IDI_M1 = 'TKTK' AND IDI_M2 = 'TOTO') OR
    (IDI_F1 = 'TITI' AND IDI_F2 = 'TUTU' AND IDI_M1 = 'TKTK' AND IDI_M2 = 'TOTO')
    ...

    @ +
    while (true) echo 'comique';
    Du comique de répétition ...
    Pour des questions de lisibilité, utilisez la balise [code]
    Si votre problème est résolu, n'oubliez pas le tag

  4. #4
    Membre expérimenté
    Avatar de ryan
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2003
    Messages
    956
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2003
    Messages : 956
    Points : 1 316
    Points
    1 316
    Billets dans le blog
    1
    Par défaut
    Hola,

    Une chose qui n'est pas claire pour moi: est-ce que le champ IDI_FORMULA est complété pour chaque enregistrement de la table? Et si oui, est-ce que ce champ contient systématiquement les 4 parents?

    Ryan
    Un ascenseur est une machine qui passe quand même la moitié de son temps à descendre.

  5. #5
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    Quel rapport avec PHP ?
    Ton message ne serait pas mieux coté SQL ? (je demande avant de déplacer)
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre actif Avatar de JmL40
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 348
    Points : 246
    Points
    246
    Par défaut
    Bonjour,

    Le champ formula n'est pas systématiquement renseigné, et un NUMERO n'a pas obligatoire 4 parents donc je peux avoir des formules du genre IDI_F1/IDI_M1 ...

    C'est un problème PHP et SQL car je vais parcourir toutes les formules à rechercher en paramètre dans mon script PHP, et exécuter l'une des deux requêtes proposées dans une boucle. Je crains donc pour les performances.

    Je voulais avoir vos avis à la fois sur le script PHP et la requête SOL.

    Cordialement
    while (true) echo 'comique';
    Du comique de répétition ...
    Pour des questions de lisibilité, utilisez la balise [code]
    Si votre problème est résolu, n'oubliez pas le tag

  7. #7
    Membre expérimenté
    Avatar de ryan
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2003
    Messages
    956
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2003
    Messages : 956
    Points : 1 316
    Points
    1 316
    Billets dans le blog
    1
    Par défaut
    Hola,

    J'ai bien peur que tu ne coupes pas à tester toutes les combinaisons dans ton query. En effet, je ne pense pas que tout ramener (800000 lignes quand même) et faire les tests en PHP soit efficace.


    A tester: une concaténation des champs IDI_F1, IDI_F2, IDI_M1 et IDI_M2 dans la clause WHERE et un test avec l'opérateur LIKE.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT * FROM IDENTITE WHERE IDI_F1+IDI_F2+IDI_M1+IDI_M2  LIKE '%TOTO%' AND DI_F1+IDI_F2+IDI_M1+IDI_M2  LIKE '%TUTU%' AND DI_F1+IDI_F2+IDI_M1+IDI_M2  LIKE '%TITI%' AND DI_F1+IDI_F2+IDI_M1+IDI_M2  LIKE '%TKTK%'
    Voir deux choses: si la concaténation est possible dans la clause WHERE et quel est l'opérateur de concaténation dans SQL Server.

    Enfin, la dernière solution, si tu peux faire des modifs à la structure de la table IDENTITE, serait de regrouper le contenu des champs IDI_F1, IDI_F2, IDI_M1 et IDI_M2 dans un seul champ, avec un séparateur quelconque, et de faire autant de LIKE sur ce champ que tu n'as de parents connus dans ton query.
    Un ascenseur est une machine qui passe quand même la moitié de son temps à descendre.

  8. #8
    Membre actif Avatar de JmL40
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 348
    Points : 246
    Points
    246
    Par défaut
    Bonjour,

    Je pourrais par exemple mettre en place une colonne calculée dans la table qui, pour chaque lignes concatène F1, F2, M1, M2.

    Ensuite dans mon "query", je recherche la combinaison passée en paramètre dans la colonne calculée.

    D'après vous, est-ce une bonne solution ?

    Cordialement
    while (true) echo 'comique';
    Du comique de répétition ...
    Pour des questions de lisibilité, utilisez la balise [code]
    Si votre problème est résolu, n'oubliez pas le tag

  9. #9
    Membre expérimenté
    Avatar de ryan
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2003
    Messages
    956
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2003
    Messages : 956
    Points : 1 316
    Points
    1 316
    Billets dans le blog
    1
    Par défaut
    Hola,

    Je pense en effet que le champ qui rassemble les données des parents va faciliter et accélérer les choses.

    Prévois un séparateur, qui peut être un espace, mais un caractère qui ne sera jamais présent dans les noms des parents offre plus de sécurité.

    Ensuite un query sur le champ concaténé, avec un LIKE sur le nom de chaque parent à rechercher, précédé et suivi d'une wildcard, ça devrait le faire.

    Autre solution: l'opérateur IN dans la clause WHERE:

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM IDENTITE WHERE  IDI_F1 IN { 'toto', 'tutu', 'titi', 'tktk' } OR IDI_F2 IN { 'toto', 'tutu', 'titi', 'tktk' } OR IDI_M1 IN { 'toto', 'tutu', 'titi', 'tktk' } OR IDI_M2 IN { 'toto', 'tutu', 'titi', 'tktk' }

    Faudrait faire un benchmark et voir ce qui est le plus rapide. Je crois me souvenir que l'opérateur LIKE n'est pas réputé pour sa rapidité...

    Ryan
    Un ascenseur est une machine qui passe quand même la moitié de son temps à descendre.

  10. #10
    Membre actif Avatar de JmL40
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 348
    Points : 246
    Points
    246
    Par défaut
    Bonjour,

    Merci pour vos réponses, je vais développer la solution du champ calculé avec le wildcard ...

    Je ne clôture pas le sujet, je reviens vers vous dans peu de temps !

    Cordialement
    while (true) echo 'comique';
    Du comique de répétition ...
    Pour des questions de lisibilité, utilisez la balise [code]
    Si votre problème est résolu, n'oubliez pas le tag

  11. #11
    Membre confirmé
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Points : 597
    Points
    597
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Pour le faire simplement et d'une manière optimisé, il vous faut refaire d'abord votre modèle.
    Vu, je suppose que F=Father et M=Mother, il faudrait d'abord commencer par référencer de manière unique chaque homme de votre base de donnée avec un identifiant, et de même pour chaque femme. Je vous laisse le soin de le faire, ce forum n'étant pas le bon pour vous faire une suggestion.
    Ensuite faire une table de jonction pour les hommes et pour les femmes avec leur identifiants respectifs en relation avec votre table identité (attention aux mots réservés de plus) est le plus simple et vous évitera une volumétrie creuse.
    Je rappelle ensuite que c'est le rôle de PHP de mettre en forme les paramètres de manière à ce qu'ils soient transmis de façon correcte au SGBDR pour le traitement approprié.

    ++

Discussions similaires

  1. [MySQL] Optimisation de scripts PHP/MySQL
    Par DgG dans le forum PHP & Base de données
    Réponses: 368
    Dernier message: 20/11/2013, 18h59
  2. [MySQL] Optimisation script PHP et Mysql
    Par Invité dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 25/06/2013, 09h39
  3. [PHP 5.4] Optimisation script php
    Par Mardewin dans le forum Langage
    Réponses: 6
    Dernier message: 10/05/2013, 11h35
  4. [Débutant] Accélérer et optimiser ses scripts PHP
    Par Metallic-84s dans le forum Langage
    Réponses: 6
    Dernier message: 24/03/2006, 12h37
  5. [MySQL] [Script]Optimisation de scripts Php/MySQL (2)
    Par copy dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 27/08/2004, 08h33

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