+1  A: 

You realize at least part of the decreasing performance is the log filling up, and that a GUID id what, 40 bytes longer than an int?

But I'm not quibbling; it's good to see someone taking actual metrics rather than just handwaving. Modded up.

tpdi
Thanks. GUID are in fact 16 bytes. I hadn't thought about the log file but it shouldn't affect performance that badly, especially when there should be no real difference, as far as the log file is concerned, between using and Integer or a GUID, so the issue must come from somewhere else.
Renaud Bompuis
+3  A: 
Rex M
Hmmm, OK, I agree that SQL Server needs to be tuned but what you say doesn't hold when you're looking at the perf of using GUID: it's degrading too quickly. We're only talking about 100k records here yet I can't insert at more than 66 records/second!
Renaud Bompuis
@Renaud see my revised answer.
Rex M
But there's still no way it should be that slow if the transactions are being managed properly.
le dorfier
@le dorfier that's my point as well, as stated in my edit. There must be something wrong - performance that low is highly suspicious.
Rex M
See my further comments in my answer.
le dorfier
Thanks for sharing your results. I'll make a few more tests and report back later.
Renaud Bompuis
Access does not degrade with 100K records unless you fail to design your Access app appropriately.
David-W-Fenton
@David when does Access start to degrade in your experience?
Rex M
We're talking Access front end to SQL Server back end, right? It only degrades if you don't program it correctly -- that can happen with 1000 records. You just have to know which operations to let Jet handle (Jet is very smart) and which ones to move server-side.
David-W-Fenton
On the other hand, if you're talking about a Jet back end (which wasn't the topic of discussion here), Access still performs very, very well with lots of records assuming the tables are properly indexed and your application is efficient in the way it uses the data.
David-W-Fenton
I think my new tests help support your view David.
Renaud Bompuis
+2  A: 

Where are you getting the data from?

Does it change the numbers if you use the Access Export menu options rather than record-at-a-time-in-a-loop?

VBA is really sensitive to the connection paramters too, and there are lots of options that aren't necessarily intuitive.

If an identity column is acceptable, why are you even considering a sequential GUID (which is something of a tacked-on facility in MSSQL last I checked).


EDIT: Looking at your code and briefly reviewing the Recordset docs on MSDN, I see you may be able to use more efficient parameters. E.g. your dbSeeChanges and dbOpenDynaset, which are appropriate if you are trying to allow for other users messing with the same rows (or needing to get back the inserted IDENTITY value or probably GUID), but I don't think you need those. In essence, after every INSERT or UPDATE, you're reading the record back from the database into VBA. I'd read through those connection config settings carefully, and I bet you'll come up with something a lot more satisfactory.

le dorfier
Renaud Bompuis
a. I'd check the GUID insertion issue from @Denis.b. Then check how you're handling your 1000-row batch transactions. You may not be getting what you expect for transaction control. Have you tried just 1 row per transaction as a worst case?
le dorfier
Actually, you got something right about the options to the recordset. dbDynaset is mandatory and dbSeeChanges is also mandatory if using an IDENTITY column as PK. What makes performance much better though is to use dbAppendOnly since we don't need to read the record after inserting it.
Renaud Bompuis
I read it that those flags are mandatory if using an IDENTITY *and* you needed to use the recordset after the insert (because otherwise the IDENTITY value wouldn't be populated. But I don't think you need to get it back.
le dorfier
+1  A: 

The last time I saw something like that (really slow insertion with GUID PK) was because of the log-file filling up. Insertion performance was dropping like a stone, pretty fast (no hard measurement, just looking at live traces, but it sure looked like it was kinda logarithmic). This was pre-loading of historical data. Moved over to identity PK, took care of actually cleaning up the log file, and everything went much better afterwards (a couple of hours where the first version took several hours and was not finished).

Also, just a thought, are there any transactions involved? Maybe SQL Server transactions create a big performance hit that access does not have (given that access is not really geared towards concurrent access).

Denis Troller
+1  A: 

My question is whether your test setup represents the reality of your application or not. In short, are you testing the right thing?

Is your app going to be appending large numbers of records one at a time?

Or is it going to be appending batches of records based on a SQL SELECT?

If the latter, you might look at trying to do it all server-side, particularly if the source table(s) in the SELECT are on the server. It's important to realize that with ODBC, a batch append is going to be sent to the SQL Server as a single insert for every single row (every similar to the recordset-based approach in your test code). If you move the same process entirely server-side, it can be done as a batch operation.

Also, you should test again using ADO instead of DAO. It may optimize the operation completely differently.

Last of all, someone brought to my attention just this past week this fascinating article by Andy Baron:

Optimizing Microsoft Office Access Applications Linked to SQL Server

I'm still absorbing the contents of that very useful article, and it discusses several issues in regard to non-GUID-specific topics that may help you optimize your process for maximum efficiency.

David-W-Fenton
For now I'm just trying to understand what affects performance. I initially wanted to test GUID insertion since it's meant to be the most expensive operation. Turns out that the test shows that recordset options are much -much- more important! Thanks for the article, it's going to help me a lot.
Renaud Bompuis
Chosen answer because the link you provided is gold to me.
Renaud Bompuis
It really is quite a good article -- I've bookmarked it and returned to it several times in the last week!
David-W-Fenton