tags:

views:

148

answers:

9

I have a large amount of data stored in an xml file 173MB (4.6 million lines) that I have stored in my winforms working directory.it is the result of writing a datatable to an XML file. The datatable was originaly populated from a query to a SQL server.

The reason that I have it stored locally rather than requesting it from the server is that the data request took upwards of 40 seconds and at times timed out and the data is static and will never change, moreover the user can be off line and still use the data.

Loading the file backinto the datatable takes 20-30 seconds..I am not too woried about the time that it took to load from disk as I let the user know that data is loading and to be patient. However I don't like the XML file format and I am looking for other ideas for diskstorage.

The datatable is only beng used as a middleman for the eventual population of a collection object. If you have sugestions I would like to hear them. Thanks

I am hoping to stay away from a database solution and lean towards a binary file approach, below is my first attempt but I get an out of memory exception:

byte[] b = null;

using (MemoryStream stream = new MemoryStream())
{
   BinaryFormatter bformatter = new BinaryFormatter();
   bformatter.Serialize(stream, timeData);
   b = stream.ToArray();
}

using (FileStream fileStream = new
   FileStream("brad.bin", FileMode.Create, FileAccess.Write))
{
   fileStream.Write(b, 0, b.Length);
}
+2  A: 

You can try using SQLite or csv-file, for example.

Li0liQ
+5  A: 

SQLite is pretty nice, you could choose from a variety of disconnected DB solutions but it really depends on the work you want to put into it and the dataset you have.

Quintin Robinson
+9  A: 

I'd look at a compact (local) database such as SQL CE or SQLite. Databases are designed for exactly this.

Joe
SQL CE fully integrates into the Visual Studio line of tools, should be easiest given that the master DB is SQL Server, and is free and freely redistributable.
Eric J.
Having used SQLite, I love it. You can use LINQ with it too.
jcollum
+1 for SQLite I've used it in numerous scenarios now and it is simply awesome.
Dillie-O
does it require an instalation of a service or application to act as a server? If so the company that I work for will not allow this
Brad
I believe SQLCE requires a separate installer for the API but it's not a client-server database as you would understand it: Databases are stored in files (with the .sdf extension) and you're in control. I've not used SQLite with .NET but in most cases it's just some extra code that you need to compile in.
Joe
I agree SQLite good if you want to go down the database route.
martinr
+1  A: 

if you are using the datatable as a middle-man and then loading from there into a collection, what about using XMLSerialize to load directly into your collection? Skipping the middle-man should give you some performance gains.

Muad'Dib
A: 

First of all... that was an ugly paragraph to read :P

Regarding your question, if you are using .net, why not go with SQL Compact (mdf file)? It is like working with sql server but the data is stored in a file.

I personally think thats the best way to go, but if you want choices then I guess you could consider

  • Excel file
  • Comma separated text file
  • MS Access Database
  • ?

Cheers!

Francisco Noriega
Damn! There were no answers when I started writing! I think I should post my answers in a quicker/dirtier way and then edit to fix/enhance/"elegantize" them!
Francisco Noriega
+1  A: 

Why is the application requesting the whole dataset every time? If you're using a database you should (imho) be treating the database similarly to your heap...
- Request what is needed as it is needed

Some operations may require comparison of different data across the whole database, but that's what SQL is for. Perform those operations in the database, not in the application.

Do you have an use-case scenario where you absolutely require the whole dataset in memory?

Dems
+2  A: 

If it can never change, why aren't you just providing it with the application installation in the first place?

Are you confused about what the terms "will never change" actually means?

As for local storage solutions, there's plenty to choose from, like SQLite which would let you use a database-solution, even if locally, without any installation hassle.

Lasse V. Karlsen
I am offering with the application instalation. I would like have it as a resource file.
Brad
If it truly never will change, and providing it with the application is a viable approach I would look into just installing a SQLite, or similar, database file to begin with, or let the application build that database file from scratch the first time run. I would, in no case, load a multi-megabyte XML file to load data, unless I need it *all*. If I only need portions of the data, I would load that portion, and nothing else, and that means something other than XML (or you're going to have to eat that XML piecemeal to extract the relevant pieces.)
Lasse V. Karlsen
The data is historical and is used to create charts of performance data. There will be apending to the data to the resource month to month - the program will be requesting these small bites of data. Is SQLite just a file and not an application? - because I could just supply the file and let the the program append the file as needed
Brad
SQLite is a database, you issue SQL against it to manipulate the contents. The upshot from a "regular" database is that no installation is necessary. On the other hand, it isn't as good/fast as a regular database engine would be, like SQL Server, but in most cases, for its intendend usage, it's faster. For the case you mention, an import file containing new data would be good enough, and would be used by a routine to generate INSERT statements against a table in a SQLite database.
Lasse V. Karlsen
A: 

I don't like XML either but I think it's the way to go if the data is entirely read-only.

I think you could well be writing XML text in standard XML text format to disk already, despite your use of a class with Binary in the name. Open it up, have a look. (Use the dd Unix tool (download some Unix tools if you don't have dd already) to grab a sample file of just the first few megabytes, open it in Wordpad or similar and take a look.)

If you want to make it not easily human readable, consider using encryption.

EDIT

That's IF your workstations are pretty much dedicated to the task and sticking 173MB of data in RAM, and working from that rather than fiddling with SQL happens to make good business sense.

martinr
A: 

Why not leave the data on the server and use some standard DataSet caching? Creating a query which returns 180Mb of data sounds like a design problem.

I believe a more appropriate solution for a historical trend would be to retrieve only those records which are currently displayed. When you want to zoom in on a part of your chart, retrieve the magnified data only.

Regarding your binary serialization, you should serialize directly to FileStream:

using (FileStream fileStream = new
   FileStream("brad.bin", FileMode.Create, FileAccess.Write))
{
   new BinaryFormatter().Serialize(fileStream, timeData);
}
Groo