A critical choice when designing your application is whether to use a DataSet or a DataReader. If you need to retrieve many records rapidly, use a DataReader. The DataReader object is fast, returning a fire hose of read-only data from the server, one record at a time. In addition, retrieving results with a DataReader requires significantly less memory than creating a DataSet. The DataReader does not allow random fetching, nor does it allow for updating the data. However, .NET data providers optimize their DataReaders for efficiently fetching large amounts of data.
In contrast, the DataSet object is a cache of disconnected data stored in memory on the client. In effect, it is a small database in itself. Because the DataSet contains all of the data that has been retrieved, you have more options in the way you can process the data. You can randomly choose records from within the DataSet and update, insert, and delete records at will. You can also manipulate relational data as XML. This flexibility provides some impressive functionality for any application, but comes with a high cost in memory consumption. In addition to keeping the entire result set in memory, the DataSet maintains both the original and the changed data, which leads to even higher memory usage. Do not use DataSets with very large result sets because the scalability of the application will be drastically reduced.