|
 |
access thread: Database application architecture
Message #1 by "Sander Groffen" <sander.groffen@z...> on Sun, 26 May 2002 12:22:32
|
|
Dear programmers,
Could someone give me advice concerning the design of application
architecture? The situation is as follows:
I am writing a client application in VB6 that allows users to view and
modify a server-side Access 2000 database (connected through a LAN). The
app displays each record of a database table as a treeview node. To create
the treeview structure, I retrieve a recordset from the database and use
it to make multiple passes. As the number of records may grow to large
amounts, this process will require an exponentially increasing amount of
time. Thus, choosing the right architecture is an important issue.
I can imagine a solution to increase performance for large databases: by
creating a server-side application that responds to a client request,
calulates the treeview structure, and sends back these data in the form of
a relatively small collection of objects corresponding with each node.
This will reduce the amount of data sent across the network, and thus
increase performance.
The problem here is that I don?t know how to make a server-app communicate
with a client-app.
- How to make the server-app respond to the client?s request?
- How to pass the object collection back to the right client?
- Is it possible to include this function in the Access database
itself ?
- Or should the server-app be a *.dll or something ?
Please excuse me if these are a lot of questions. I would really
appreciate if someone could suggest a good way to get started on this.
Regards,
Sander
Message #2 by "Phillip Johnson" <phillip.johnson@e...> on Sun, 26 May 2002 20:39:07
|
|
Ssander, rather than change the architecture of the application so
severeley, is it not the case that with an ActiveX connection, if you
supply a SQL statement as the command you would only get the required data
coming back through the network anyway and not the entire database?
If you do need to distribute the application, there is a technology called
DCOM (which is like COM components (ie dll files etc) only for distributed
applications.
Hope this helps,
Kind regards, Phillip
> Dear programmers,
> Could someone give me advice concerning the design of application
a> rchitecture? The situation is as follows:
> I am writing a client application in VB6 that allows users to view and
m> odify a server-side Access 2000 database (connected through a LAN). The
a> pp displays each record of a database table as a treeview node. To
create
t> he treeview structure, I retrieve a recordset from the database and use
i> t to make multiple passes. As the number of records may grow to large
a> mounts, this process will require an exponentially increasing amount of
t> ime. Thus, choosing the right architecture is an important issue.
> I can imagine a solution to increase performance for large databases: by
c> reating a server-side application that responds to a client request,
c> alulates the treeview structure, and sends back these data in the form
of
a> relatively small collection of objects corresponding with each node.
T> his will reduce the amount of data sent across the network, and thus
i> ncrease performance.
> The problem here is that I don?t know how to make a server-app
communicate
w> ith a client-app.
-> How to make the server-app respond to the client?s request?
-> How to pass the object collection back to the right client?
-> Is it possible to include this function in the Access database
i> tself ?
-> Or should the server-app be a *.dll or something ?
> Please excuse me if these are a lot of questions. I would really
a> ppreciate if someone could suggest a good way to get started on this.
>
R> egards,
S> ander
Message #3 by "Randy Cornish" <rlcornish@c...> on Mon, 27 May 2002 01:20:09
|
|
I would suggest that the best architectural advice is to use MSDE or SQL
Server instead of Access. As the amount of data grows, your app will get
progressively slower and slower and there is not much you can do to
optimize it. Access is a file-based product, not a server-based. That
means that ALL SQL processing is done on the client machine. If you want
two rows out of 2,000, all 2,000 will go across the LAN and THEN the two
rows you want will be selected out.
You may get some relief if you use an ActiveX EXE on the server that
processes the SQL and sends only the results, but DCOM is complicated
(and on its way out) and cross-machine marshalling is expensive.
I would try and emulate the ideas that are coming out of VB.NET as much
as possible - web services that dispense XML (or some form of delimited
ASCII that can be rehydrated on the client), disconnected datasets.
You can abstract most of this away from the main part of your app by
having your User Interface (your TreeView) talk to business objects which
know how to manage themselves (persist changes, rollback, ...). In this
way, you can abstract off the database access so that any changes to how
you store data will only affect a small percentage of your app. This
allows you to start with Access and grow into a bigger solution at a
later time.
Use a server DB product (MSDE, SQL Server) for best performance.
R
> Ssander, rather than change the architecture of the application so
s> evereley, is it not the case that with an ActiveX connection, if you
s> upply a SQL statement as the command you would only get the required
data
c> oming back through the network anyway and not the entire database?
> If you do need to distribute the application, there is a technology
called
D> COM (which is like COM components (ie dll files etc) only for
distributed
a> pplications.
> Hope this helps,
> Kind regards, Phillip
> > Dear programmers,
> > Could someone give me advice concerning the design of application
a> > rchitecture? The situation is as follows:
> > I am writing a client application in VB6 that allows users to view
and
m> > odify a server-side Access 2000 database (connected through a LAN).
The
a> > pp displays each record of a database table as a treeview node. To
c> reate
t> > he treeview structure, I retrieve a recordset from the database and
use
i> > t to make multiple passes. As the number of records may grow to
large
a> > mounts, this process will require an exponentially increasing amount
of
t> > ime. Thus, choosing the right architecture is an important issue.
> > I can imagine a solution to increase performance for large databases:
by
c> > reating a server-side application that responds to a client request,
c> > alulates the treeview structure, and sends back these data in the
form
o> f
a> > relatively small collection of objects corresponding with each
node.
T> > his will reduce the amount of data sent across the network, and thus
i> > ncrease performance.
> > The problem here is that I don?t know how to make a server-app
c> ommunicate
w> > ith a client-app.
-> > How to make the server-app respond to the client?s request?
-> > How to pass the object collection back to the right client?
-> > Is it possible to include this function in the Access database
i> > tself ?
-> > Or should the server-app be a *.dll or something ?
> > Please excuse me if these are a lot of questions. I would really
a> > ppreciate if someone could suggest a good way to get started on this.
> >
R> > egards,
S> > ander
Message #4 by "Carnley, Dave" <dcarnley@a...> on Tue, 28 May 2002 10:01:41 -0500
|
|
Writing your front-end in VB6 will allow you to use ADO to communicate with
the back-end database. SO what was said about all the data moving over the
network to the client before any SQL processing is done is probably not
accurate. If you were using Access as your front-end connected to another
Access database then there are situations where that would be the case.
However, you will be using pure ADO so the SQL processing will be done by
JET on the server side.
The first thing you should do is make sure your database is design well
without regard to the front-end display requirements. I've seen Access
databases with millions of rows perform very well if designed correctly.
How to do that is another topic... normalize...
To make most efficient use of Access as back-end database you'll want to use
stored queries as much as possible. In ADO these will appear as tables, so
you will still be writing SELECT statements but it will be like this
"SELECT * FROM qry_GetCustomers WHERE CustID =" & iCustID
and if you looked at the definition of "qry_GetCustomers" it might join 3
tables or something... keep the complexity on the back-end.
I try to always use class structures in my ADO apps. I hesitate to call it
object oriented but it is more or less that. I use a class for each
underlying database table. For each base-table class:
-> Write get/let methods for each database field (note: not all fields have
both get and let. Autonumber ID fields would not have a let for example).
-> Include Boolean variables tracked internally to the class called EXISTING
and DIRTY. In each property LET procedure, compare the new value to the
existing value and if different, the flag DIRTY is set to true.
Public Property Let PremierFlag(NewVal As Boolean)
If mPremierFlag <> NewVal Then
mPremierFlag = NewVal
mDirty = True
End If
End Property
-> Write one or more "Find" methods that will accept as parameters the
primary key or alternate keys and will connect to the database and retrieve
the specified record, and populate the object. If the record is found and
populated correctly, the function returns TRUE. If not found then it returns
FALSE. The FIND method sets the EXISTING flag to TRUE and DIRTY to FALSE if
the record exists in the database. Be sure to use the stored queries in the
find procedures.
Public Function FindByID(CustID as integer) as Boolean
Public Function FindBySSN(CustSSN as string) as Boolean
...
-> Write a "NEW" method that sets up a new object that will eventually be
saved to the database. The NEW method should set EXISTING to FALSE and
DIRTY to FALSE
-> Write "Save" and "Revert" methods for each base-table class. The SAVE
method checks the DIRTY flag, if the object is not dirty it does not need to
be saved. Then it checks EXISTING to know if it needs to do an insert or
update. Using access it may not be efficient to use stored INSERT or UPDATE
queries but doing so will make your code more consistent and easier to
migrate to SQL server one day. (note - revert is just 'new' and 'find'...)
-> A base-table class may contain collections of objects from related
tables. I might have a ORDERS class and one of its properties is a
collection of Ordered_items. Each object in the collection of order-Items
is itself an instance of a base-table class order_item. Order_item should
have all the features of a base-table class I just described... To access a
member of the collection have a GET procedure on the parent object that
accepts a parameter
PUBLIC FUNCTION GET_OrderItem (LineNo as integer) as clsOrder_Item
also have an add function
PUBLIC FUNTION ADD_OrderItem (Item as clsOrder_Item) as Integer (returns
LineNo)
** use a global object to represent your database connection. Get your DSN
name, establish the connection, and use that global object in all your FIND
and SAVE methods. That way, if you have to change how you connect to the
database, you only have to change it in one place. Chances are good you
WILL have to change how you connect to the database... Murphy's Law...
** now that you have a "layer" of code that completely isolates your
database, its time to design your user interface. it sounds like you
already have a pretty complete idea for this. Perhaps you could use a
collection of top-level objects as the highest level of the tree. On each
tree node keep the key of the record, use this key to look up each object in
the collection. Each of those objects could then contain a collection of
the nodes below it, and so on however deep you need to go. You should also
track in the treeview a flag that indicates if a particular node has been
expanded already or not -then when the user expands that node, if never
expanded before, go to the database and get the next level of nodes for just
that particular branch. If that node has been expanded before, no call to
the db is needed since that data for that node is already in memory in a
collection of objects... This will prevent your app from trying to load all
the data for the entire tree structure all at once. By linking the
tree-view interface to the base-table classes, the tree-view only needs to
say "this field changed, update it to the object" and "user clicked Save,
call the Save method". Very clean and neat.
Ok That's all I have time to write right now. Have fun, plan ahead, and
think about "layers".
David
-----Original Message-----
From: Sander Groffen [mailto:sander.groffen@z...]
Sent: Sunday, May 26, 2002 7:23 AM
To: Access
Subject: [access] Database application architecture
Dear programmers,
Could someone give me advice concerning the design of application
architecture? The situation is as follows:
I am writing a client application in VB6 that allows users to view and
modify a server-side Access 2000 database (connected through a LAN). The
app displays each record of a database table as a treeview node. To create
the treeview structure, I retrieve a recordset from the database and use
it to make multiple passes. As the number of records may grow to large
amounts, this process will require an exponentially increasing amount of
time. Thus, choosing the right architecture is an important issue.
I can imagine a solution to increase performance for large databases: by
creating a server-side application that responds to a client request,
calulates the treeview structure, and sends back these data in the form of
a relatively small collection of objects corresponding with each node.
This will reduce the amount of data sent across the network, and thus
increase performance.
The problem here is that I don't know how to make a server-app communicate
with a client-app.
- How to make the server-app respond to the client's request?
- How to pass the object collection back to the right client?
- Is it possible to include this function in the Access database
itself ?
- Or should the server-app be a *.dll or something ?
Please excuse me if these are a lot of questions. I would really
appreciate if someone could suggest a good way to get started on this.
Regards,
Sander
Message #5 by "Sander Groffen" <sander.groffen@z...> on Wed, 29 May 2002 22:47:11
|
|
Thank you very much for the helpful comments. Especially Dave's comments
were very valuable to me. Regards, Sander
Message #6 by "Randy Cornish" <rlcornish@c...> on Thu, 30 May 2002 01:27:33
|
|
With all due respect, I disagree that any of the SQL processing will
occur on the server. In order to verify that this is still true, I e-
mailed an expert on Access DAO and ADO (over 10 books to his credit). It
is still true that it is the LOCAL Jet DLLs that do all the work. The
server is nothing more than a big, "slow" disk drive.
The one thing that he DID remind me that I did not put in my first
posting is that when you query a large table, you get only the INDEXES
for all the rows, not the actual data. Then, Jet uses random file access
and the index to retrieve only the data row(s) it needs. So, if you have
500,000 records and your index (or Primary Key) is a Long, you will get 4
bytes * 500K, or 2MB of data across the LAN before you can fetch your
target record.
I stand by my earlier post. Abstract your data access code so that when
the day comes that Access is too slow, you can move to SQL Server or MSDE
without tearing your whole application apart.
R
Writing your front-end in VB6 will allow you to use ADO to communicate
with
the back-end database. SO what was said about all the data moving over
the
network to the client before any SQL processing is done is probably not
accurate. If you were using Access as your front-end connected to another
Access database then there are situations where that would be the case.
However, you will be using pure ADO so the SQL processing will be done by
JET on the server side.
The first thing you should do is make sure your database is design well
without regard to the front-end display requirements. I've seen Access
databases with millions of rows perform very well if designed correctly.
How to do that is another topic... normalize...
To make most efficient use of Access as back-end database you'll want to
use
stored queries as much as possible. In ADO these will appear as tables,
so
you will still be writing SELECT statements but it will be like this
"SELECT * FROM qry_GetCustomers WHERE CustID =" & iCustID
and if you looked at the definition of "qry_GetCustomers" it might join 3
tables or something... keep the complexity on the back-end.
I try to always use class structures in my ADO apps. I hesitate to call
it
object oriented but it is more or less that. I use a class for each
underlying database table. For each base-table class:
-> Write get/let methods for each database field (note: not all fields
have
both get and let. Autonumber ID fields would not have a let for
example).
-> Include Boolean variables tracked internally to the class called
EXISTING
and DIRTY. In each property LET procedure, compare the new value to the
existing value and if different, the flag DIRTY is set to true.
Public Property Let PremierFlag(NewVal As Boolean)
If mPremierFlag <> NewVal Then
mPremierFlag = NewVal
mDirty = True
End If
End Property
-> Write one or more "Find" methods that will accept as parameters the
primary key or alternate keys and will connect to the database and
retrieve
the specified record, and populate the object. If the record is found and
populated correctly, the function returns TRUE. If not found then it
returns
FALSE. The FIND method sets the EXISTING flag to TRUE and DIRTY to FALSE
if
the record exists in the database. Be sure to use the stored queries in
the
find procedures.
Public Function FindByID(CustID as integer) as Boolean
Public Function FindBySSN(CustSSN as string) as Boolean
...
-> Write a "NEW" method that sets up a new object that will eventually be
saved to the database. The NEW method should set EXISTING to FALSE and
DIRTY to FALSE
-> Write "Save" and "Revert" methods for each base-table class. The SAVE
method checks the DIRTY flag, if the object is not dirty it does not need
to
be saved. Then it checks EXISTING to know if it needs to do an insert or
update. Using access it may not be efficient to use stored INSERT or
UPDATE
queries but doing so will make your code more consistent and easier to
migrate to SQL server one day. (note - revert is just 'new'
and 'find'...)
-> A base-table class may contain collections of objects from related
tables. I might have a ORDERS class and one of its properties is a
collection of Ordered_items. Each object in the collection of order-Items
is itself an instance of a base-table class order_item. Order_item should
have all the features of a base-table class I just described... To
access a
member of the collection have a GET procedure on the parent object that
accepts a parameter
PUBLIC FUNCTION GET_OrderItem (LineNo as integer) as clsOrder_Item
also have an add function
PUBLIC FUNTION ADD_OrderItem (Item as clsOrder_Item) as Integer (returns
LineNo)
** use a global object to represent your database connection. Get your
DSN
name, establish the connection, and use that global object in all your
FIND
and SAVE methods. That way, if you have to change how you connect to the
database, you only have to change it in one place. Chances are good you
WILL have to change how you connect to the database... Murphy's Law...
** now that you have a "layer" of code that completely isolates your
database, its time to design your user interface. it sounds like you
already have a pretty complete idea for this. Perhaps you could use a
collection of top-level objects as the highest level of the tree. On each
tree node keep the key of the record, use this key to look up each object
in
the collection. Each of those objects could then contain a collection of
the nodes below it, and so on however deep you need to go. You should
also
track in the treeview a flag that indicates if a particular node has been
expanded already or not -then when the user expands that node, if never
expanded before, go to the database and get the next level of nodes for
just
that particular branch. If that node has been expanded before, no call to
the db is needed since that data for that node is already in memory in a
collection of objects... This will prevent your app from trying to load
all
the data for the entire tree structure all at once. By linking the
tree-view interface to the base-table classes, the tree-view only needs to
say "this field changed, update it to the object" and "user clicked Save,
call the Save method". Very clean and neat.
Ok That's all I have time to write right now. Have fun, plan ahead, and
think about "layers".
David
-----Original Message-----
From: Sander Groffen [mailto:sander.groffen@z...]
Sent: Sunday, May 26, 2002 7:23 AM
To: Access
Subject: [access] Database application architecture
Dear programmers,
Could someone give me advice concerning the design of application
architecture? The situation is as follows:
I am writing a client application in VB6 that allows users to view and
modify a server-side Access 2000 database (connected through a LAN). The
app displays each record of a database table as a treeview node. To
create
the treeview structure, I retrieve a recordset from the database and use
it to make multiple passes. As the number of records may grow to large
amounts, this process will require an exponentially increasing amount of
time. Thus, choosing the right architecture is an important issue.
I can imagine a solution to increase performance for large databases: by
creating a server-side application that responds to a client request,
calulates the treeview structure, and sends back these data in the form
of
a relatively small collection of objects corresponding with each node.
This will reduce the amount of data sent across the network, and thus
increase performance.
The problem here is that I don't know how to make a server-app
communicate
with a client-app.
- How to make the server-app respond to the client's request?
- How to pass the object collection back to the right client?
- Is it possible to include this function in the Access database
itself ?
- Or should the server-app be a *.dll or something ?
Please excuse me if these are a lot of questions. I would really
appreciate if someone could suggest a good way to get started on this.
Regards,
Sander
Message #7 by "Leo Scott" <leoscott@c...> on Wed, 29 May 2002 22:23:11 -0700
|
|
You are incorrect. If you have a persisted query, i.e., stored query, in a
backend database on a network the front end Jet drivers do not process the
SQL. They have no way of knowing what the SQL statement is in the query.
It exists entirely on the backend database. As far as where the processing
occurs in a query in the front end database or a query created in the code,
it depends on where the cursor is. I have done quite a bit of work with an
Access database on my local computer, in Southern Calif., downloading major
portions of our corporate Oracle warehouse, in New York. While optimizing
the process I watched network traffic, cpu load, and memory usage in task
manager.
To download all the data in a table with 200,000 rows if I SELECT * FROM
[TableName] with a server side cursor it uses virtually no memory or cpu
time and returns the recordset in 5-10 seconds with no significant network
usage. Now when I move through the recordset and append the data to a local
table the traffic starts coming across the network but memory usage does not
grow significantly.
If I try the same thing with a client side cursor memory and network traffic
go through the roof. In fact there are some tables in the warehouse that I
cannot download with ADO because they exceed 1.5gig of memory usage, even
though I have 2.5gig counting virtual memory, and Access VBA errors out. In
the case of the client side cursor it is putting the entire recordset into
memory on the local machine when you open it.
I don't know who your friend is who has written the books, but I can say I
have found many books with poorly written code for VB/VBA, even some from
Microsoft. Things like:
Dim RS as New Recordset
instead of;
Dim RS as ADODB.Recordset
Set RS = New ADODB.Recordset
There are books that don't even declare a variables type, making it a
variant. Ask your friend how I can have a recordset that is easily 20meg in
size with 200,000 records and move anywhere in it using find without
bringing major portions of the recordset across the network. Stop and think
about what you said. Do you thing when you go to a web site that the
database resides on the same machine as the web server. Not for any major
web site. How could such a web site sustain 1000s of data accesses a second
if the web server was constantly processing the queries by pulling all that
data across the network. The web site processes the requests sends the
queries to the data server who processes the queries/stored procedures and
just sends as little data across the network as necessary to satisfy the web
servers request. The model you prescribed would bring most major web sites
to their knees, Amazon, Dell, Compaq, etc.
|-----Original Message-----
|From: Randy Cornish [mailto:rlcornish@c...]
|Sent: Thursday, May 30, 2002 1:28 AM
|To: Access
|Subject: [access] RE: Database application architecture
|
|
|With all due respect, I disagree that any of the SQL processing will
|occur on the server. In order to verify that this is still true, I e-
|mailed an expert on Access DAO and ADO (over 10 books to his credit). It
|is still true that it is the LOCAL Jet DLLs that do all the work. The
|server is nothing more than a big, "slow" disk drive.
|
|The one thing that he DID remind me that I did not put in my first
|posting is that when you query a large table, you get only the INDEXES
|for all the rows, not the actual data. Then, Jet uses random file access
|and the index to retrieve only the data row(s) it needs. So, if you have
|500,000 records and your index (or Primary Key) is a Long, you will get 4
|bytes * 500K, or 2MB of data across the LAN before you can fetch your
|target record.
|
|I stand by my earlier post. Abstract your data access code so that when
|the day comes that Access is too slow, you can move to SQL Server or MSDE
|without tearing your whole application apart.
Message #8 by Arthur Maloney <ArthurMaloney@s...> on Thu, 30 May 2002 09:19:39 +0100
|
|
Hello Randy,
Read your comments with interest.
I have an Access 97 0.7 million records 100 meg backend it is slow
across a network.
Do you think it would be quicker to run if
1 Convert backend to Access 2k. On each user's machine have Access 2k front end
using ADO to connect to backend)
2 Install MSDE on each user's machine and convert backend to Srvr2k tables
End client does not want Srvr2k as such installed on a network
--
Best regards,
Arthur mailto:ArthurMaloney@s...
Message #9 by braxis@b... on Thu, 30 May 2002 10:18:48
|
|
Leo
Randy and yourself seem to be talking about completly different scenarios -
and are both right!
You're describing the working of a proper client-server database, Oracle
or SQL-Server. In this case the database server does do all the work. If
you've designed your database properly then network traffic will be
minimised.
Randy is talking about the file-server model that Access uses when both
front and back end are Access databases. In this case there is no database
engine running on the server where the backend database resides. Access
and JET are unlikely to have been installed on the file server. The only
database engine available to the user, JET, runs on the users machine. JET
therefore has to pull all the data across the network before it can
process a query. Native Access databases doesn't support server side
cursors, as there is no server to run them - all cursors are client side.
As you say, Amazon, Dell, Compaq, etc. websites would fail extremly
quickly using this model. Which is why, I hope, they are not using Access
databases to store their data!
Brian
> You are incorrect. If you have a persisted query, i.e., stored query,
in a
backend database on a network the front end Jet drivers do not process the
SQL. They have no way of knowing what the SQL statement is in the query.
It exists entirely on the backend database. As far as where the processing
occurs in a query in the front end database or a query created in the code,
it depends on where the cursor is. I have done quite a bit of work with an
Access database on my local computer, in Southern Calif., downloading major
portions of our corporate Oracle warehouse, in New York. While optimizing
the process I watched network traffic, cpu load, and memory usage in task
manager.
To download all the data in a table with 200,000 rows if I SELECT * FROM
[TableName] with a server side cursor it uses virtually no memory or cpu
time and returns the recordset in 5-10 seconds with no significant network
usage. Now when I move through the recordset and append the data to a
local
table the traffic starts coming across the network but memory usage does
not
grow significantly.
If I try the same thing with a client side cursor memory and network
traffic
go through the roof. In fact there are some tables in the warehouse that I
cannot download with ADO because they exceed 1.5gig of memory usage, even
though I have 2.5gig counting virtual memory, and Access VBA errors out.
In
the case of the client side cursor it is putting the entire recordset into
memory on the local machine when you open it.
I don't know who your friend is who has written the books, but I can say I
have found many books with poorly written code for VB/VBA, even some from
Microsoft. Things like:
Dim RS as New Recordset
instead of;
Dim RS as ADODB.Recordset
Set RS = New ADODB.Recordset
There are books that don't even declare a variables type, making it a
variant. Ask your friend how I can have a recordset that is easily 20meg
in
size with 200,000 records and move anywhere in it using find without
bringing major portions of the recordset across the network. Stop and
think
about what you said. Do you thing when you go to a web site that the
database resides on the same machine as the web server. Not for any major
web site. How could such a web site sustain 1000s of data accesses a
second
if the web server was constantly processing the queries by pulling all that
data across the network. The web site processes the requests sends the
queries to the data server who processes the queries/stored procedures and
just sends as little data across the network as necessary to satisfy the
web
servers request. The model you prescribed would bring most major web sites
to their knees, Amazon, Dell, Compaq, etc.
Message #10 by "Randy Cornish" <rlcornish@c...> on Fri, 31 May 2002 01:29:19
|
|
Leo,
As posting #9 (Brian) points out, I believe we are talking about two
different things. Your example in your posting is an Oracle back-end. I
am talking about an Access backend with a VB client (using Jet). In that
scenario, Jet has access to the queries and everything (including index
information) within the Jet object model. I stand by my statement.
The original posting (Sander) was a question about using Access as a
backend server.
I heartily agree that most "real" database servers (SQL Server, Oracle,
et.al.) do all the SQL processing. Access is not among that family
(although this is in no way an attack on Access - it is superb at what it
does, server up small quantities of data (under 1 million records) to
small quantities of users (under 10).
Can I assume we are back in alignment or is this issue still open for
discussion?
R
> You are incorrect. If you have a persisted query, i.e., stored query,
in a
backend database on a network the front end Jet drivers do not process the
SQL. They have no way of knowing what the SQL statement is in the query.
It exists entirely on the backend database. As far as where the
processing
occurs in a query in the front end database or a query created in the
code,
it depends on where the cursor is. I have done quite a bit of work with
an
Access database on my local computer, in Southern Calif., downloading
major
portions of our corporate Oracle warehouse, in New York. While optimizing
the process I watched network traffic, cpu load, and memory usage in task
manager.
To download all the data in a table with 200,000 rows if I SELECT * FROM
[TableName] with a server side cursor it uses virtually no memory or cpu
time and returns the recordset in 5-10 seconds with no significant network
usage. Now when I move through the recordset and append the data to a
local
table the traffic starts coming across the network but memory usage does
not
grow significantly.
If I try the same thing with a client side cursor memory and network
traffic
go through the roof. In fact there are some tables in the warehouse that
I
cannot download with ADO because they exceed 1.5gig of memory usage, even
though I have 2.5gig counting virtual memory, and Access VBA errors out.
In
the case of the client side cursor it is putting the entire recordset into
memory on the local machine when you open it.
I don't know who your friend is who has written the books, but I can say I
have found many books with poorly written code for VB/VBA, even some from
Microsoft. Things like:
Dim RS as New Recordset
instead of;
Dim RS as ADODB.Recordset
Set RS = New ADODB.Recordset
There are books that don't even declare a variables type, making it a
variant. Ask your friend how I can have a recordset that is easily 20meg
in
size with 200,000 records and move anywhere in it using find without
bringing major portions of the recordset across the network. Stop and
think
about what you said. Do you thing when you go to a web site that the
database resides on the same machine as the web server. Not for any major
web site. How could such a web site sustain 1000s of data accesses a
second
if the web server was constantly processing the queries by pulling all
that
data across the network. The web site processes the requests sends the
queries to the data server who processes the queries/stored procedures and
just sends as little data across the network as necessary to satisfy the
web
servers request. The model you prescribed would bring most major web
sites
to their knees, Amazon, Dell, Compaq, etc.
|-----Original Message-----
|From: Randy Cornish [mailto:rlcornish@c...]
|Sent: Thursday, May 30, 2002 1:28 AM
|To: Access
|Subject: [access] RE: Database application architecture
|
|
|With all due respect, I disagree that any of the SQL processing will
|occur on the server. In order to verify that this is still true, I e-
|mailed an expert on Access DAO and ADO (over 10 books to his credit). It
|is still true that it is the LOCAL Jet DLLs that do all the work. The
|server is nothing more than a big, "slow" disk drive.
|
|The one thing that he DID remind me that I did not put in my first
|posting is that when you query a large table, you get only the INDEXES
|for all the rows, not the actual data. Then, Jet uses random file access
|and the index to retrieve only the data row(s) it needs. So, if you have
|500,000 records and your index (or Primary Key) is a Long, you will get 4
|bytes * 500K, or 2MB of data across the LAN before you can fetch your
|target record.
|
|I stand by my earlier post. Abstract your data access code so that when
|the day comes that Access is too slow, you can move to SQL Server or MSDE
|without tearing your whole application apart.
Message #11 by "Randy Cornish" <rlcornish@c...> on Fri, 31 May 2002 01:42:19
|
|
Converting to Access 2000 will not really buy you any speed improvement
that I can think of (mileage may vary). In fact, it now stores all
string as double-byte (for Unicode) and could conceivably be slower if
you move a lot of string data around.
What you could do is audit your use of Indexes and make sure that for any
query with filter criteria that you are running against indexes. This
might provide marginal improvements. You would have to write some timing
code to determine that. Use caution as the second time you run a query,
you will often get a much quicker return due to the way Jet caches the
query optimization. I would run a query 10 times and divide the result
by 10 to get an average execution time to use as a baseline.
I understand that ADO is actually slower than Jet for Access because Jet
is optimized for Access.
You only need to install either MSDE or SQL Server on the server, not the
client. Once your data is housed in MSDE/SQLServer2K, you can use ADO to
query against it and performance will jump dramatically (assuming you
have laid it out properly). SQLServer2K is easier since you have a GUI
interface to administer the database, test stored procedures and monitor
performance. SQL Books Online is also excellent. HOWEVER, SQLServer2000
requires a LOT more administration effort than "good ol' Access". It's a
tradeoff. You've got to decide what your client has a appetite for and
what they can handle if you're no longer there (and what you can handle).
If I have misinterpreted your question, please restate.
R
> Hello Randy,
Read your comments with interest.
I have an Access 97 0.7 million records 100 meg backend it is slow
across a network.
Do you think it would be quicker to run if
1 Convert backend to Access 2k. On each user's machine have Access 2k
front end
using ADO to connect to backend)
2 Install MSDE on each user's machine and convert backend to Srvr2k
tables
End client does not want Srvr2k as such installed on a network
--
Best regards,
Arthur mailto:ArthurMaloney@s...
Message #12 by "Leo Scott" <leoscott@c...> on Thu, 30 May 2002 20:13:43 -0700
|
|
We probably are but as soon as I get some free time I want to do some
testing on my local network. There is no doubt that if a server has no Jet
drivers loaded on it and you are just storing and accessing an .mdb file
there that the processing has to occur on the client, but I want to do some
testing to see if the server does the processing if it has Access installed
on the server. I'm not sure I can determine that but I'm going to look at
some CPU utilization data accessing a legnthy query on one machine while
running it locally then accessing it from an ADO connection on another
machine where the recordset just opens the persisted query name. If you are
correct in the second scenerio the CPU load should not spike as high or as
long on the server as when it processes it locally.
|-----Original Message-----
|From: Randy Cornish [mailto:rlcornish@c...]
|Sent: Friday, May 31, 2002 1:29 AM
|To: Access
|Subject: [access] RE: Database application architecture
|
|
|Leo,
|
|As posting #9 (Brian) points out, I believe we are talking about two
|different things. Your example in your posting is an Oracle back-end. I
|am talking about an Access backend with a VB client (using Jet). In that
|scenario, Jet has access to the queries and everything (including index
|information) within the Jet object model. I stand by my statement.
|
|The original posting (Sander) was a question about using Access as a
|backend server.
|
|I heartily agree that most "real" database servers (SQL Server, Oracle,
|et.al.) do all the SQL processing. Access is not among that family
|(although this is in no way an attack on Access - it is superb at what it
|does, server up small quantities of data (under 1 million records) to
|small quantities of users (under 10).
|
|Can I assume we are back in alignment or is this issue still open for
|discussion?
|
|R
|
|
 |