À l'aide de “DANS” dans une clause where, où le nombre d'éléments dans le jeu est très grand
J'ai une situation où je dois faire une mise à jour sur un très grand nombre de lignes que je ne peux l'identifier par leur ID (depuis la cible enregistrements sont sélectionnés par l'utilisateur et n'ont rien en commun, sinon c'est le jeu d'enregistrements de l'utilisateur souhaite modifier). La même propriété est en cours de mise à jour sur tous ces dossiers, donc je souhaiterais-je faire un seul appel de mise à JOUR.
Est-il une mauvaise pratique ou est-il une meilleure façon de faire cette mise à jour de l'aide "OÙ EN (1,2,3,4,.....10000)" dans l'instruction de mise à JOUR?
Serait-il plus judicieux d'utiliser des instructions update individuelles pour chaque enregistrement et de les coller en une seule opération? Droit maintenant, je travaille avec SQL Server et Access, mais,si possible, j'aimerais vous entendre plus large les solutions les plus pratiques à travers n'importe quel type de base de données relationnelle.
Ouais, des milliers de personnes. Mon échantillon jusqu'il y a "10000" comme le dernier indice. Je pense que ce sera le nombre maximum - au moins dans le court terme.
OriginalL'auteur Karim | 2009-02-10
Vous devez vous connecter pour publier un commentaire.
Je serais toujours utiliser
à moins que votre clause a été bêtement grand, qui ne devrait pas vraiment se passer de la saisie de l'utilisateur.
edit: Par exemple, les Rails ne beaucoup de derrière les coulisses
Il serait certainement pas mieux de faire des mise à jour des déclarations en une seule transaction.
WHERE id IN (@val1,@val2,@val3,@val4,..... @val10000)
. Ce serait beaucoup plus efficace.OriginalL'auteur DanSingerman
Une autre alternative est de stocker ces nombres dans une table temp et de l'utiliser dans une jointure de faire la mise à jour. Si vous êtes en mesure d'exécuter une seule instruction de mise à jour est certainement mieux que l'exécution d'une instruction par enregistrement.
Les accès de ce faire. J'ai souvent l'utilisation d'une table temporaire, voire permanente définie -- lié à un contrôle d'INTERFACE utilisateur. Ainsi, lorsque l'utilisateur est de sélectionner les articles à traiter, ces éléments sont arriver le pavillon ou l'insérer dans la table temporaire. Lorsque l'utilisateur clique sur OK, une requête de mise à JOUR joint à la table temp.
Juste être sûr que si le tableau de mise à jour est une table liée sur un Serveur SQL server que la table temporaire est aussi là. Sinon, l'Accès peut essayer de tirer l'ensemble de la table en mémoire pour faire la mise à jour puis de l'envoyer au Serveur SQL server. Vous pouvez également utiliser une perm table avec un identifiant de transaction
(suite) - Laissez-moi savoir si vous souhaitez plus d'informations sur la table permanente méthode et je vais poster une réponse
N'est pas la mise à jour de la table temporaire suite à la même question que la mise à jour de la table d'origine? Vous devez insérer le nombre d'Id dans une déclaration ou de les faire dans de nombreux états. Comment est-ce mieux que l'original?
OriginalL'auteur Otávio Décio
Comment pouvez-vous générer de la clause?
Si il y a t-il une autre instruction SELECT qui génère ces valeurs, vous pouvez simplement brancher que dans la mise à JOUR comme suit:
Dans certains RDBMses, vous obtiendrez de meilleures performances en utilisant le EXISTE syntaxe, qui devrait ressembler à ceci:
Ah, c'est une honte. Ensuite, j'irais pour la table temp approche proposée par ocdecio. Juste ajouter des trucs à la table temp que l'utilisateur fait leur choix.
OriginalL'auteur JosephStyons
Dans Oracle il y a une limite de valeurs que vous pouvez mettre dans une clause IN.
Donc, il vaut mieux utiliser un OU x=1 ou x=2 ... ceux qui ne sont pas limitées, autant que je sache.
OriginalL'auteur HeDinges
Je voudrais utiliser une table-variable /temp-table; insérer les valeurs dans le présent, et de se joindre à elle. Ensuite, vous pouvez utiliser le même jeu plusieurs fois. Cela fonctionne particulièrement bien si vous êtes (par exemple) la transmission d'un fichier CSV des codes d'identification de type varchar. Comme un Serveur SQL exemple:
Cam - bravo, idéal.
OriginalL'auteur Marc Gravell
Sans savoir ce qu'est un "très grand" nombre de ID est peut-être, je me risquerais une supposition. 😉
Puisque vous utilisez Access comme base de données, le nombre d'ID ne peut pas être que élevé. En supposant que nous parlons moins de, disons, 10 000 numéros et nous devrions connaître les limites de l'récipients pour contenir l'ID (quel est le langage utilisé pour le front-end?), Je collerais un
UPDATE
déclaration; si c'est plus lisible et facile pour effectuer des opérations de maintenance sur le tard. Sinon je serais diviser en plusieurs instructions à l'aide de quelques petits malins de la logique. Quelque chose comme séparer l'instruction en plusieurs instructions dans un, dix, cent, mille... ID par instruction.Ensuite, je partirais à la DB de l'optimiseur pour exécuter l'instruction(s) aussi efficace que possible. Je serais probablement faire un "expliquer" sur la ou les requêtes pour s'assurer que rien de stupide se passe bien.
Mais dans mon expérience, il est très souvent sur OK pour quitter ce genre d'optimisation pour le gestionnaire de base de données elle-même. La seule chose qui prend le plus de temps est généralement la connexion à la base de données, donc si vous pouvez exécuter toutes les requêtes au sein de la même connexion, il est donc normalement pas de problèmes. Assurez-vous que vous envoyez tous les
UPDATE
instructions avant de commencer à chercher et attendre que les ensembles de résultats de revenir. 🙂Oui, c'est un assez grand nombre (ou un entier de type long...). Mais avez-vous essayé d'utiliser quelque chose près que le nombre de lignes dans une base de données Access? 😉 C'était plus ce que je pensais.
OriginalL'auteur Tooony
En général, il y a plusieurs choses à considérer.
Nous avons récemment modifié notre système pour limiter la taille de l'en-clauses et toujours utiliser des variables liées à la car cela réduit le nombre d'instructions SQL et donc à l'amélioration de la performance. Fondamentalement, nous générons nos instructions SQL et exécuter plusieurs instructions si la clause dépasse une certaine taille. Nous ne le faisons pas pour les mises à jour de sorte que nous n'avons pas eu à nous soucier du verrouillage. Vous aurez.
À l'aide d'une table temporaire peut ne pas améliorer les performances, car vous devez remplir le temp de table avec l'Id. L'expérimentation et les tests de performances peuvent vous dire la réponse ici.
Un seul À la clause est très facile à comprendre et à maintenir. C'est probablement ce qui devrait vous inquiéter en premier. Si vous trouvez que les performances des requêtes est mauvaise, vous pourriez vouloir essayer une stratégie différente et voir si ça aide, mais n'optimisent pas prématurément. La clause est sémantiquement correct donc le laisser seul s'il n'est pas cassé.
OriginalL'auteur Mr. Shiny and New 安宇
Si vous étiez sur Oracle, je vous recommande d'utiliser les fonctions de table, semblable à Marc Gravel.
Hm. Il a demandé un "large les solutions les plus pratiques à travers n'importe quel type de base de données relationnelle". Je ne suis pas sûr si Oracle est le seul db avec les fonctions de table, mais cet avis s'applique à toute db qui prend en charge ce genre de fonctionnalité. J'ai donné un Oracle exemple parce que c'est ce sur quoi je travaille la plupart du temps. :\
+1, les OP en effet demandé une solution pour d'autres fournisseurs.
OriginalL'auteur jimmyorr
Je ne connais pas le type de valeurs dans votre liste. Si ils sont la plupart des valeurs de 1 à 10 000, vous pourriez être en mesure de les traiter pour obtenir quelque chose comme:
Ou, si le PAS DANS la liste serait encore longue, le traitement de la liste et de générer un tas d'ENTRE états:
Et ainsi de suite.
Le dernier de tous, vous n'avez pas à vous soucier de la façon dont le Jet sera procédé À un article si vous utilisez une requête directe. Vous ne pouvez pas le faire dans le code, mais vous pourriez avoir enregistré un objet QueryDef qui est défini comme un passthrough et de modifier la clause where dans le code au moment de l'exécution pour l'utilisation de votre liste. Puis c'est tous passé à SQL Server et SQL Server va décider de la meilleure façon de le traiter.
OriginalL'auteur David-W-Fenton
Il y a plusieurs façons de répondre à un grand ensemble de valeurs dans une condition where
L'Aide De Tables Temporaires
Insérer les valeurs dans une table temporaire avec une seule colonne.
Créer un INDEX UNIQUE sur la colonne.
JOINTURE INTERNE de la table avec la récente création de la table temporaire
À l'aide du tableau-comme les fonctionnalités de SQL Server
SQL prend en charge un tableau comme fonctionnalité
vérifier cette lien pour une documentation plus complète.
EXEMPLE DE SYNTAXE :
Requête à l'aide de
INNER JOIN #Id id id.id = A.
OriginalL'auteur Aswath