2009-12-29 13 views
1

J'ai une table SQL Server sans index, et je ne peux pas les ajouter. Il y a des millions d'enregistrements dans cette table, et je ne peux pas obtenir tous les enregistrements avec une seule requête en raison d'une mémoire insuffisante.Comment obtenir des données de table SQL Server complètement par petites pièces sans index

Comment puis-je obtenir tous les enregistrements en petites portions - par exemple 100 enregistrements par portion?

+0

C'est un triste jour pour les administrateurs de bases de données. –

+0

Cela ressemble à une question d'examen, pas quelque chose qui se produirait réellement dans le monde réel. –

+0

Déjà fait – user224564

Répondre

0

La seule solution est - pour sélectionner toute la table que j'ai besoin de vider, dans la table temporaire avec la colonne d'identité. C'est ... une solution acceptable, puisque j'ai des serveurs d'applications et de bases de données séparés, et que le serveur DB dispose de suffisamment de mémoire pour cela. Mais probablement il y a une solution plus efficace?

1

Comment essayez-vous de lire les enregistrements? Si vous utilisez un SqlDataReader, vous ne devriez pas avoir de problèmes de mémoire.


const string QUERY = "SELECT * FROM MyTable"; 
using (var conn = new SqlConnection(CONNECTION_STRING)) 
{ 
    using (var cmd = new SqlCommand(QUERY, conn)) 
    { 
     using (var reader = cmd.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       // Use properties and methods of the reader to access the current row 
      } 
     } 
    } 
} 

Cela vous passe une ligne à la fois à travers la connexion de base de données. La connexion effectuera la mise en mémoire tampon pour vous, en amenant plusieurs lignes de la base de données et en vous les transmettant une à la fois.

+0

Et il ne consommera pas de mémoire supplémentaire à la fois côté client et serveur? Si cela ne fait que mettre en cache toute la table du côté client, c'est mauvais pour moi. S'il crée une table temporaire avec index et l'utilise - ce n'est pas bon non plus car dans ce cas, il est plus pratique pour moi de gérer cette table à ma manière. Comment alors cela fonctionne sans index dans le tableau? Peut-il être reproduit en utilisant seulement les requêtes SQL habituelles sur SqlConnection ouvert? – user224564

+0

Cela ne fonctionne pas pour les grandes tables (avec quelques millions d'enregistrements - l'exception disant que "la table est trop grande" est levée.) – user224564

+0

Veuillez publier l'exception complète Post ex.ToString(). –

1

Ceci est l'un des rares cas où un curseur peut être utilisé dans son but réel.

Vous pouvez créer un curseur statiс (qui créera une copie des données de la table, mais dans la base de données temporaire du serveur plutôt que du côté client, et le trier) et parcourir ce curseur.

0

Une solution consiste à utiliser un curseur côté serveur, comme suggéré par Quassnoi. L'inconvénient de cela est qu'il devra être un curseur statique, ce qui signifie qu'une copie de la table entière sera créée dans tempdb.

Une autre solution consiste à traiter du côté client d'une manière orientée flux, ligne par ligne (ie curseur côté client.):

using(SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) 
{ 
    while (rdr.Read()) 
    { 
    -- process one row here 
    } 
} 

De cette façon, vous pouvez traiter une grande ligne du jeu sans brûler tous vos mémoire côté client.