2009-05-15 4 views
1

J'ai deux requêtes MySQL qui à la fois insèrent des données dans une table. Tous les deux ont le format suivant:Unite deux requêtes MySQL avec UNION ou par programme

CREATE TABLE IF NOT EXISTS `data` (
`id` BIGINT NOT NULL AUTO_INCREMENT UNIQUE, 
PRIMARY KEY (`id`) 
) 
SELECT `field1`, `field2` 
WHERE `active` = 1 

Les seules différences entre les deux requêtes sont comment field1 et field2 sont déterminés, et quelques différences mineures dans la clause de conditions. Les deux courent jusqu'à 12K et plus d'enregistrements.

Maintenant, ce sera plus efficace:

A. Exécuter les requêtes séparément:

if (mysql_query($query1)) { 
    return mysql_query($query2); 
} 
return false; 

B. OU combiner les deux requêtes avec UNION, et exécuter une fois:

$query = 'SELECT `field1`, `field2` WHERE `active` = 1 
      UNION 
      SELECT DO_ONE(`field1`), DO_TWO(`field2`) WHERE `active` = 1 
      ORDER BY `field1`'; 
return mysql_query('CREATE TABLE IF NOT EXISTS `data` (
`id` BIGINT NOT NULL AUTO_INCREMENT UNIQUE, 
PRIMARY KEY (`id`) 
) ' . $query) 

Les données de l'une requête est inutile sans les données de l'autre, donc les deux doivent réussir. DO_ONE et DO_TWO sont des fonctions MySQL définies par l'utilisateur qui modifient les données de champ en fonction de certaines spécifications.

+0

Au moins superficiellement, il semble que vous obtenez gauche plus bas-fonds de séries précédentes des requêtes si votre table cible existe déjà. De plus, comme vous disposez d'une clé primaire générée automatiquement, vous pouvez continuer à insérer de nouveaux enregistrements dans la table aussi longtemps que vous le souhaitez (vous n'aurez plus besoin d'espace disque avant de manquer de nombres). –

+1

La version UNION n'assure aucun enregistrement en double dans le jeu de résultats. la version des requêtes séparées ne le fait pas. Eh bien, la colonne 'id' assure en fait que les enregistrements seront tous distincts, mais il pourrait y avoir des enregistrements répétés avec les mêmes données dans les autres colonnes (mais des valeurs d'id différentes). Cela compte probablement - utilisez UNION. –

Répondre

1

La réponse d'Aaronmccall est probablement la meilleure en général - l'approche UNION le fait en un appel SQL. En général, ce sera le plus «efficace», mais il pourrait y avoir des problèmes secondaires qui pourraient entrer en jeu et affecter la mesure de «efficace» pour votre application particulière. Plus précisément, si l'UNION requiert une table temporaire pour collecter les résultats intermédiaires et que vous travaillez avec de très grands ensembles de données, il peut s'avérer plus efficace de faire deux SELECT SELECT distincts dans la nouvelle table dans votre cas particulier. Cela dépend du fonctionnement interne, des optimisations effectuées, etc. dans le moteur de base de données (ce qui peut changer en fonction de la version du moteur de base de données que vous utilisez). En fin de compte, la seule façon de répondre à votre question sur une question spécifique comme celle-ci pourrait être de faire des minutages pour votre application et environnement particulier.Vous pourriez aussi vouloir considérer que la différence entre le temps requis pour deux requêtes séparées et une requête "tout en un" peut être insignifiant dans le grand schéma des choses ... vous parlez probablement d'une différence d'un quelques millisecondes (ou même quelques microsecondes?) sauf si votre base de données mysql est sur un serveur séparé avec d'énormes problèmes de latence. Si vous effectuez des milliers de ces appels en une seule fois, la différence peut être significative, mais si vous effectuez un ou deux de ces appels et que votre application passe 99,99% de son temps à exécuter d'autres tâches, alors la différence entre deux probablement ne sera même pas remarqué.

--- Lawrence

+0

L'une des requêtes s'exécute en millisecondes. L'autre prend quelques minutes à cause d'une procédure de storec plutôt compliquée. J'ai décidé de m'éloigner du proc stocké pour optimiser la requête. – Jrgns

0

Vos options font des choses différentes. La première renvoie les résultats de la deuxième requête si la première requête s'exécute correctement (ce qui est BTW indépendant des résultats qu'elle renvoie, elle peut renvoyer un ensemble de lignes vide). La deuxième renvoie les résultats de la première requête et de la deuxième requête ensemble. La première option me semble assez inutile, probablement ce que vous voulez faire est ce que vous avez fait avec l'UNION (à moins que je ne vous ai mal compris).

EDIT: Après avoir lu votre commentaire, je pense que vous êtes après quelque chose comme ceci:

SELECT vrai où (EXISTS (SELECT champ1, champ2 ...) ET EXISTE (SELECT champ1, champ2 ...)) . De cette façon, vous n'aurez qu'une requête à la base de données, qui évolue mieux, prend moins de ressources du pool de connexions et ne double pas l'impact de la latence si vous avez votre moteur de base de données sur un serveur différent, mais vous interrompez toujours la requête si la première condition échoue, ce qui est l'amélioration des performances que vous recherchez avec les requêtes séparées imbriquées.

En tant qu'optimisation, essayez d'avoir d'abord la condition qui s'exécutera plus rapidement, au cas où ils ne sont pas les mêmes. Je suppose que si l'un d'entre eux nécessite ces calculs sur le terrain serait plus lent.

+0

Aucune des options ne renverra les jeux de résultats. Les deux retourneront faux si l'un ou l'autre des deux a échoué, ou un objet résultat. Comme ces requêtes insèrent uniquement des données, il n'est pas nécessaire d'interroger les objets de résultat. Il sera seulement interprété comme un booléen, pour voir si l'insertion a été exécutée avec succès. – Jrgns

+0

Je suppose que vous voulez dire que dans le cas de l'union, si le premier retourne vide, le second retournera vide aussi à cause des requêtes que vous faites. Qu'est-ce que UNION va faire est de rassembler les résultats de chacune des requêtes, ce qui signifie que vous obtiendriez un vrai si l'un renvoie des enregistrements et l'autre ne le fait pas. Quoi qu'il en soit, je vais modifier ma réponse maintenant que je sais ce que vous voulez un peu mieux. – palako

0

L'approche UNION devrait certainement être plus rapide en raison du coût de faire deux appels API mysql de php vs un.