0
votes

Suis-je impatient ou pas efficace?

So Sumet-le rapidement, j'ai une base de données code> SQLServer CODE> (Utilisation de SSMS pour travailler avec elle) et il a une table avec Crony_num strong>, puis une description forte> colonne. E.g 16548221587 | Petite brosse à cheveux. Code> J'ai l'index sur Colonne de commande_num forte>.

J'ai ensuite une application vb.net, je veux essentiellement que l'utilisateur permet à l'utilisateur de mettre un fichier .txt avec un fichier massif Liste des order_nums strong> (> 150 000, 1 par ligne) et ce que cela fait est lit ces lignes par ligne, puis la base de données de la recherche, ajoute-t-il tout à une table TEMP, puis Streamwrites code> à un fichier "résultats" .txt. P>

En ce qui concerne le titre de cette question, je le demande parce que mon code que je posterai ci-dessous, fonctionne! Et je l'amette à la lecture et à la recherche et à la recherche et à l'insérer chaque trouvaille dans la table Temp à 0,427 secondes une recherche mais posez ceci avec 150 000 enregistrements en regardant plus de 16 heures! Donc, c'est ce que je me demande, je fais de cela une voie de pointe de pointe ou que je m'attendais à beaucoup trop de lire / de trouver et de récupérer ce nombre de documents et attendez-vous à devenir plus rapide? P>

select o.Order_num, t.description
from Temp_data o
join OrderTable on t.Order_num= o.Order_num


select x.Order_num, x.description
from OrderTable x
where Order_num in (select Order_num from Temp_data)


select x.Order_num,x.description
from OrderTable x
cross apply (select o.Order_num from Temp_data o where o.Order_num= x.Order_num) ord


1 commentaires

Index que la colonne Order_num de Table Table Table.


4 Réponses :


1
votes

Je ne connais pas la structure des procédures stockées que vous utilisez dans la commande, mais je suppose que la plupart du temps, les opérations sur le serveur SQL et la communication entre l'application et le serveur SQL occupent la plupart du temps. . Pensez donc à l'optimalisation - comme envoyer tous les chiffres à la fois à la procédure. Vous n'aurez pas à appeler la procédure xy fois. Et tenter d'examiner le plan d'exécution des procédures stockées - existe-t-il quelque chose qui peut être amélioré?


0 commentaires

1
votes

Je suggérerais les optimisations suivantes.

Premièrement, insert en vrac dans la table ID de commande temporaire directement à partir du fichier TXT. Si vous avez un ordre_num dans chaque ligne, cela le fera. xxx

pour le insert en vrac pour fonctionner le fichier Doit être accessible pour SQL Server, sur la machine SQL Server ou via un emplacement partagé sur le réseau.

Deuxièmement, exécutez une requête pour obtenir toutes les descriptions d'une fois en vous joignant à la table d'identité de commande temporaire: xxx

Vous avez maintenant les résultats en deux étapes.


3 commentaires

Cela ne fonctionnera que si elles peuvent obtenir le fichier sur le serveur où SQL Server est en cours d'exécution.


@Marcin ou il doit être accessible sur un chemin réseau par la machine SQL Server. Bon point; Voyons voir ce que SOP dit.


Salut les gars, alors j'ai fait ma propre version de Sqlbulkcopy à l'aide d'un jeu de données et tout ce qui fonctionne instantané ou au moins très très vite, j'utilise alors toute la requête de jointure, mais même pour faire 100 ordres_numbers (le retour 170) prend toujours environ 30 secondes qui est assez lent pour une requête de jointure, des idées?



3
votes

Le problème avec votre code est que vous exécutez cette commande SQL 150k fois. Cela ne va jamais travailler (rapide).

Ce que vous pouvez faire est de lire les valeurs 150K à partir du fichier d'abord, puis insérez à l'aide de sqlbulkcopy code> dans une table, Par exemple, comme indiqué dans cette réponse . Fondamentalement, faites ce que votre dbo.ordersotemp code> est dans votre code VB.NET - tout à la fois au lieu d'une ligne à la fois. Cela devrait prendre quelques secondes au plus, compte tenu de la latence de votre requête actuelle. P>

pour la requête suivante: p> xxx pré>

Je suppose Les commandes code> peuvent contenir plusieurs enregistrements par ordre_num code> (Vous avez mentionné Retourner 170 lignes pour 100 commandes), vous pouvez utiliser des index comme tels: P>

CREATE UNIQUE CLUSTERED INDEX ux ON TempOrderIdTable (order_num);


4 commentaires

C'est vraiment très lent, quelle est la taille de ce OrderTable ?! Voir ma réponse mise à jour pour une suggestion sur l'indexation.


C'est environ 10 millions de lignes!


@Marcinj L'indexation sur la table TEMP doit faire le tour et SQLBulkCopy est préférable à partager un fichier. Puis-je vous suggérer que vous ajoutez la requête de jointure à la réponse pour la compléter et le OP pour accepter votre réponse?


Salut @marcinj! Donc, j'ai fait exactement comme vous l'avez dit, ajouté les index exacts et tous, mais que les résultats de la requête prennent toujours 35 secondes (pour 100 billets, 170 résultats)! J'ai un sentiment et c'est quelque chose que j'ai oublié de mentionner (excuses) est que les descriptions sont nvarchar (max) car ils peuvent être assez longs parfois, peut-être peut-être que cela a une incidence sur celle-ci?



1
votes

Juste pour une référence future (copie en vrac et indices sont très certainement la réponse) ... Ne créez pas une commande pour chaque itération d'une boucle, ajoutant des paramètres sur chaque itération et les propriétés de réglage de la commande. Ils sont les mêmes pour chaque boucle; Seule la valeur des paramètres change.

    Dim cmd As New SqlCommand("dbo.OrdersToTemp", con)
    cmd.CommandType = CommandType.StoredProcedure
    cmd.Parameters.Add("@OrderNum", SqlDbType.NVarChar)
    cmd.CommandTimeout = 3000
    For Each word As String In Result
        cmd.Parameters("@OrderNum").Value = word
        cmd.ExecuteNonQuery()
    Next


0 commentaires