Where does an Access query run using linked tables? - sql-server

I use MS Access 2010 on my PC, to link MS SQL tables from our server on cloud.
When I run a query I wrote on Access on my PC involving the lined tables, does the query retreive data from the SQL server over the connection, or is there a cashed data locally on my PC that is used instead?
Simply the question is: In case of using linked tables in Access, does querying these tables run locally where Access database is in use or on the server?

The query will run locally with ordinary queries and linked tables. This means that Access will need to pull all of the data from the linked tables and filter the rows locally. This can be very bad for performance if your WHERE clause only returns a small percentage of rows.
An alternative would be to use pass through queries where the query is executed on the server. This means only the data you need will pass over the network and the performance could be far better.

Related

Alternate to SQL Server Linked Server

I am trying to build a program that compares 2 database servers that have exact table but in some table have additional column. I am using linked server to connect these 2 database servers.
But I found a problem, when I try to compare some data the connection is mostly timeout. And when I check Activity Monitor and Execution plan, more than 90% is in remote query - this makes comparing 1 record that has 5 child entries run for 5-7 minutes.
This is a sample query that I try to run.
Select
pol.PO_TXN_ID, pol.Pol_Num
From
ServerA.InstanceA.dbo.POLine pol
Where
not exist (Select 1
From ServerB.InstanceA.dbo.POLine pol2
where pol.PO_TXN_ID = pol2.PO_TXN_ID
and pol.Pol_Num = pol2.Pol_Num)
I tried using OPENROWSET, but our administrator does not permit to install it on the production server.
Is there any alternative that I can use to optimize my query instead using linked server?
Options:
OpenQuery() / 4 part naming with temp tables.
ETL (eg: SQL Server Integration Services)
The problem with linked servers especially with 4 part naming like in your example:
The query engine doesn't know how to optimize it. He can't access statistics on the linked servers
Resulting in doing full table scans, pulling all the data to the source SQL server and then processing it. (High network IO, Bad execution plans, resulting in long running queries)
Option 1
Create a temp table (preferably with indexes)
Query the linked server with OPENQUERY and preferably a filter condition. eg:
CREATE TABLE #MyTempTable(Id INT NOT NULL PRIMARY KEY, /*Other columns*/)
INSERT INTO #MyTempTable(Id, , /*Other columns*/)
SELECT *
FROM OPENQUERY(ServerA, 'SELECT Id, /*Other columns*/ FROM Table WHERE /*Condition*/')
Use the temp table(s) to do your calculation.
Still needs at least 1 linked server
OPENQUERY has better performance when your database is not a SQL Server (e.g. Postgres, MySql, Oracle,...) as the query is executed on the linked server instead of pulling all the data to the source server.
Option 2
You can use an ETL tool like SQL Server Integration Services (SSIS)
Load the data from the 2 servers
Use a Slowly changing dimension or lookup component to determine the differences.
Insert/update what you want/need
No linked servers are needed, SSIS can connect to the databases directly

Very slow queries in MS Access with joined MS SQL table via ODBC

What is the best solution when I would like to use an Access front-end application with some linked table (via ODBC) from MSSQL Server?
The difficulty of this for me is that I have to use complex queries with many multiple joins (and functions called from queries).
It is very-very slow because of the joins between the two DB (and there is a lot of data in some tables, the 2 GB Access mdb limit is the reason of the MSSQL DB upgrade).
Pass-through query doesn't help because of the joined Access tables.
With OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0'... it is still slow in SQL Server too. I tried ODBC linked view with WHERE clause from MSSQL, but it
seems as slow as the full table.
I have to move all of joined Access tables to the MSSQL DB and convert all queries to Pass-Through? Is there any other solution?
I have to move all of joined Access tables to the MSSQL DB
Yes, definitely.
and convert all queries to Pass-Through?
Not necessarily, only those that are still slow.
"Normal" INNER JOIN queries, using only linked tables from one server database, are handled by Access and the ODBC driver in a way that everything is processed on the server. They should be (more or less) as fast as when run on the server (or as Pass-Through query).
Only "complex" queries, especially involving multiple INNER and OUTER JOINs, won't work like that. You'll notice that they are still very slow when running on linked tables. These need to be changed to Pass-Through queries.
Edit: I just noticed
functions called from queries
You can't call VBA functions from PT queries, and they will again kill performance when called from Access queries running on linked MSSQL tables (because they have to be processed locally).
You'll need to learn to create views in MSSQL, probably also user defined functions and/or stored procedures.
In the long run, you'll find that views are actually easier to manage than PT queries.

MS Access to MS SQL Linked data - extremely long updates & deletes?

I have an MS Access application with data in a separate access mdb. We need to move the data to MS SQL. Previously when I did this is worked very well - dramatic speed improvements. In this new upgrade however, we are seeing some problems with translating of the SQL from Access to SQL.
We have the solution separated into an APP mdb and a DATA MDB. We use Linked-tables to join the two. After migrating the data to SQL server, we created an ODBC link, then re-pointed the linked-tables to the SQL data source over ODBC. We would expect the SQL command generated by Access, to be simply transferred to SQL server, for SQL server to operate on same using its normal efficiency and power.
When I put a trace on SQL Profiler, instead of seeing for example a simple "Delete * from table", we see a series of delete statements, one for each record in the table ...
We see the same thing for updates - where we would expect for example "insert into table1 (select a,b,c from table2)...) to be sent as an SQL string, to be executed on the server, we instead see a series of insert statements, one per row being inserted, being sent to the server.
It seems that Access is trying to work out the logic for everything but select statements client side and not letting MS SQL server take care of things as one would expect.
Anyone experienced this behaviour before and can offer a suggestion to resolve?
thanks.

Copy access database to SQL server periodically

I have an access 2003 database that holds all of my business data. This access database gets updated every few hours during the day.
We're currently writing a website that will need to use the data from the access database. This website (for the time being) will have only read only capabilities. Meaning there will only need to be one way transfer of data (Access -> SQL).
I'm imaging there's a way to perform this data migration from access to SQL server programatically. Does anyone have any links to something I can read about?
If this practice sounds odd, and you'd like to suggest another way to do this (or a situation where data can go both ways (Access -> SQL, SQL -> Access), that's perfectly fine.
The company is going to continue using Access 2003 for their business functionality. There's no way around that. But I'd like to build the (readonly) website on top of SQL Server.
The strategy you outlined can be very challenging. You could use INSERT queries to copy new Access rows to SQL Server, as described in another answer.
However, if you have changes to existing Access rows, and you also want those changes propagated to SQL Server, it won't be so simple. And it will be more complicated still if you want deleted Access rows deleted from SQL Server, too.
It seems more reasonable to me to use a different approach. Migrate the data to SQL Server once. Then replace the tables in your Access database with ODBC links to the SQL Server tables. Thereafter, changes to the data from within your Access application will not require a separate synchronization step ... they will already be in SQL Server. And you won't need to write any code to synchronize them.
If your concern is that the connections between the web server and SQL Server be read-only, just set them up that way. You can still independently allow read-write permissions for your Access application.
To do the initial data migration and set the SQL Server automatically, I would use the SQL Server Migration Assistant. The only thing you should definitely change that I can think of would be to turn off the Identity property on any columns that have it - to be explained below (MS Access calls Identity autonumber). Once you have your tables loaded, you can set up a dsnless connection to the database (and tables) you just created.
I haven't used the method just linked, but I believe it allows you to use SQL Server authentication to connect to the db. The benefit of using this method is you can easily change which SQL Server instance and/or database your are connecting to for development and testing.
There might be a better, automated way, but you can create several insert queries doing left joins from the primary key of the Access table to the SQL Server table, and putting a WHERE clause that specifies the SQL Server PrimaryKey must be null. This is why you need to turn off the Identity property in the SQL Server tables, so that you can insert the new data.
Finally, put the name of each query in one function, then run the function periodically.
I have used Microsoft's free SQL Server Migration Assistant (SSMA) to migrate Access to SQL Server. The tool is very simple to use. The only problem I have encountered with the tool was overloaded data types when migrating. What I mean by this is a small string will get converted to a NVARCHAR(MAX) in some instances. Otherwise, the tool is very handy and can be reused after setting up a 'profile'.

MS Access 2007 queries does't run on SQL Server 2008

I am developing an application in C# VS 2010 past 4 months. I used MS Access 2007 to store my nearly 20 tables successfully.
Today I realized that my data base cannot be handled consistently by MS Access 2007. Hence I decided to go for SQL Server 2008 R2 Express with Upsizing wizard and it worked really great!
However, when I tried to run various options of my already well developed application, It kept throwing error each time when a query is fired to SQL Server.
I understood that Many of the stuffs of SQL supported by MS Access are not supported by MS SQL Server
For example: query with date, for representing date format when we use '#', SQL Server 2008 won' t recognize it.
Also, for Bool value, MS Access stores it as True and False where as SQL Server uses 0.
These all queries worked perfect with Access 07
I am sure that there must be some method so that SQL Server can understand MS access queries.
Or will I have to edit my whole application?? It will be as good as digging a mine for earning gold..
I have changed all data access objects such as reader, adapter, command, connection to SQL data objects using System.Data.SqlClient.
So, It is not the problem.
Please help me asap.
Thank you.
You cannot force SQL Server to run the MS Access queries. These queries will need to be rewritten to use T-SQL instead of the query language that MS Access uses.
I feel your pain, I just had to rewrite a large MS Access application (over 1k queries) that needed to be recreated to be used in SQL Server.
There will be some queries that might be able to be ported over directly but as you noticed queries with date, and even some of the aggregate functions (First(), etc) are not used in SQL Server and those queries will need to be changed.
Here is a link with some info on converting Access to SQL
Converting Access Queries to SQL Server
You are right that, most of the time, you cannot just take the SQL of a query from Access and run it within SQL Server. It may work for very simple queries, but usually you need to tweak them.
There are a few steps I would take:
Extract your queries (which I presume are in your code), and re-create them in your Access database. Make sure they work there as normal Access queries.
(you can for instance simply add some code to your app to print all queries to files so you don't have to mess with parameters, then just copy/paste them in your Access DB).
The point is simply to have working queries within Access.
Use SSMA from Microsoft for helping you to move your queries to SQL Server. It does a good job of translating them into T-SQL.
You may still have to convert some troublesome queries by hand, but it shouldn't be that many and usually the conversion is not difficult.
Once converted to T-SQL, just re-inject these working queries into your code, or keep the complex queries in SQL Server as views (which it usually be faster as SQL Server will have already created its execution plan, rather than your application sending raw SQL that the server needs to analyse).
As you pointed out, there could be some issues if your fields use some features that don't cross-over to SQL Server properly.
Look at your tables in Access and do some cleanup before attempting to convert:
For booleans fields:
Make sure you set their default values to 0 or 1 (they should not be empty).
Required fields must be non-null:
Make sure that any fields that you have set as 'Required' does not contain any NULL values in its data.
Unique indexes cannot ignore Null:
Check that your indexes are not set to be both 'Unique' and 'Ignore null'.
All tables must have clean primary keys:
Make sure all your tables have a unique primary key that doesn't have Null values in their data.

Resources