2017-06-30 4 views
1

Je travaille dans un grand ensemble de données sur 134 millions de lignes que je voudrais faire une requête de sélection avec une insertion dans une table. Ceci est ma table SQL script (SQL Fiddle).Efficacité de traitement de la comparaison de requêtes SQL, toute meilleure solution?

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
Id | Emitter | EmitterIBAN       | Receiver | ReceiverIBAN       |   Adresss       |  Value 
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
1, Ernst,   HR53 8827 2118 4692 8207 5,   Kimbra,   CH20 1042 6T0N MDTG JT47 U,      3256 Arrowood Point   0002,  121.72 
2, Keene,   SK81 1004 7484 7505 6308 9259,  Torrance,  RO23 ZWTR OJKK VAU9 T5P4 2GDY,     35197 Green Ridge Way,     82.52 
3, Ernst,   HR53 8827 2118 4692 8207 5,   Kimbra,   CH20 1042 6T0N MDTG JT47 U,      3256 Arrowood Point   0048,  51.81 
4, Korie,   ME43 9833 9830 7367 4239 60,Roy,  IL69   9686 1536 8102 2219 165,      5 Swallow Alley,       88.01 
5, Ernst,   HR53 8827 2118 4692 8207 5,   Kimbra,   CH20 1042 6T0N MDTG JT47 U,      3256 Arrowood Point   0001,  133.99 
6, Charmine,  BG92 TOXX 8380 785I JKRQ JS,   Sarette,  MU67 RYRU 9293 5875 6859 7111 075X HR,   8 Sage Place,       36.30 
7, Ernst,   HR53 8827 2118 4692 8207 5,   Kimbra,   CH20 1042 6T0N MDTG JT47 U,      3256 Arrowood Point   0004,  186.99 

Et je sélectionne mes données avec cette requête


Select count(1) as NumberOperation, 
     MAX(Emitter) as EmitterName, 
     EmitterIban, 
     MAX(Receiver) as ReceiverName, 
     ReceiverIban, 
     MAX(ReceiverAddress) as ReceiverAddress, 
     SUM([Value]) as SumValues 
FROM TableEsperadoceTransaction 
Group By EmitterIban, 
     ReceiverIban 

Et je reçois le résultat suivant

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
NumberOperation | Emitter | EmitterIBAN       | Receiver | ReceiverIBAN       |   Adresss       |  SumValue 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
4,    Ernst,   HR53 8827 2118 4692 8207 5,   Kimbra,   CH20 1042 6T0N MDTG JT47 U,      3256 Arrowood Point   0002,  494,51 
1,    Keene,   SK81 1004 7484 7505 6308 9259,  Torrance,  RO23 ZWTR OJKK VAU9 T5P4 2GDY,     35197 Green Ridge Way,     82.52 
1,    Korie,   ME43 9833 9830 7367 4239 60,Roy,  IL69   9686 1536 8102 2219 165,      5 Swallow Alley,       88.01 
1,    Charmine,  BG92 TOXX 8380 785I JKRQ JS,   Sarette,  MU67 RYRU 9293 5875 6859 7111 075X HR,   8 Sage Place,       36.30 

J'ai aussi cette solution


SELECT DISTINCT * 
FROM (SELECT Count(1)  AS NumberOperation, 
       emitteriban AS _EmitterIban, 
       receiveriban AS _ReceiverIban, 
       Sum([value]) AS SumValues 
     FROM tableesperadocetransaction 
     GROUP BY emitteriban, 
        receiveriban) tmp_T 
     LEFT JOIN tableesperadocetransaction 
       ON tableesperadocetransaction.emitteriban = tmp_T._emitteriban 
       AND tableesperadocetransaction.receiveriban = 
        tmp_T._receiveriban 

Et je aime savoir quelle est la meilleure solution mise ween this two et s'il y a une requête plus efficace que ça?

Merci

+1

le premier devrait plus efficent .. vous n'avez pas adhérer et table temporaire .. doivent donc travailler plus vite .. Essayez d'utiliser – scaisEdge

+3

SET STATISTICS IO; avant d'exécuter les deux et de comparer le nombre de lectures logiques voir aussi qui s'exécute plus vite! En fin de compte, cela dépend de la structure de votre base de données, en particulier en ce qui concerne l'indexation – JeffUK

+0

Question bien écrite, mais je ne suis pas sûr qu'il fallait le demander ... il serait sûrement plus facile de mesurer la performance réelle sur votre propre serveur, plutôt que de nous demander lequel sera probablement plus rapide. –

Répondre

1

La deuxième requête est plus lente parce que:

  1. Il a une LEFT JOIN
  2. Il a une sous-requête
  3. Il a un SELECT DISTINCT
  4. A une * au lieu de noms de colonnes

Le premier est la manière la plus naturelle de le faire.

Il y a beaucoup de choses à faire pour améliorer les performances des requêtes et ce qu'il faut éviter. Voir par exemple: MSDN on improving queries

+1

Salut @TheEsisia merci pour la réponse et le lien je pense qu'il est vraiment important que je devrais le lire pour les futures requêtes pensez-vous qu'il existe une meilleure solution pour mon cas ou le premier est suffisant – Esperadoce

+0

@Esperadoce Comme je l'ai dit, votre première solution est très naturel. À moins que cela ne cause des problèmes, vous n'avez rien à changer. Mais si c'est très lent, vous pouvez envisager d'ajouter des index à votre table comme expliqué dans le lien. Bonne chance! – TheEsnSiavashi

0

La première requête devrait être beaucoup plus efficace.

Si vous voulez vraiment accélérer les choses, vous devez vous assurer que vous avez un index de couverture avec EmitterIban, ReceiverIban comme clé.

+0

vous voulez créer un index avec EmitterIabn et ReceiverIban dans un index excuse je ne suis pas bon dans sql et je voudrais savoir pourquoi est-ce mieux que d'utiliser un index pour EmitterIban et un pour ReceiverIban? Oui – Esperadoce

+0

... En fonction de votre requête, quelque chose le long de ces lignes ... CREATE INDEX NONCLUSTERED ix_TableEsperadoceTransaction_EmitterIban_ReceiverIban SUR dbo.TableEsperadoceTransaction ( \t EmitterIban ASC, ReceiverIban ASC \t) Include ( \t Emitter, \t récepteur, \t ReceiverAddress, \t Valeur \t AVEC (FILLFACTOR = 95) SUR [PRIMAIRE]; –

0

Vous pouvez essayer ceci.

Vous obtenez MIN (id), après l'utiliser pour INNER JOIN. C'est aussi un moyen.

SELECT 
tmp.NumberOperation 
,tb.Emitter 
,tmp.EmitterIban 
,tb.Receiver 
,tmp.ReceiverIban 
,tb.Adresss 
,tmp.SumValues 
FROM (SELECT Count(1)  AS NumberOperation, 
       emitteriban AS EmitterIban, 
       receiveriban AS ReceiverIban, 
       Sum([value]) AS SumValues, 
       MIN(Id)  AS Id 
     FROM tableesperadocetransaction 
     GROUP BY emitteriban, 
        receiveriban) tmp 
     INNER JOIN tableesperadocetransaction tb 
       ON tableesperadocetransaction.id = tmp.Id