Link to home
Start Free TrialLog in
Avatar of dbit
dbit

asked on

Need to call inline table function without passing parameters or speed up view calling linked server

Hi,

First a bit of background.
I have two SQL 2005 servers.
All of the below are executed on the primary server (ServerA).
The data resides on the second server (ServerB) which is set up as a linked server (LinkedServerB) on ServerA

I have a legacy application that runs queries agains ServerB. I need to move an instance of this application into a firewall and the easiest way to do this it to keep the data on ServerB, create a linked server to ServerB from ServerA and to replace all the tables on ServerA with views that has exactly the same names as the tables on ServerA. The views then make calles to the talbes on ServerB.

Testing performace the following became clear:
1) If I run the following from SQL Management Studio the result comes back sub-sceond
     SELECT *  FROM [LinkedServerB].[Database1].dbo.[Table1] with (nolock)  WHERE sharecode = 'KWV'

2) If I create a view on ServerA called Table1 that does a select against [LinkedServerB].[Database1].dbo.[Table1] in exactly the same way as no 1 above ( SELECT *  FROM [LinkedServerB].[Database1].dbo.[Table1] with (nolock)), then the following query takes op to 50 seconds to complete:
     SELECT *  FROM [ServerA].[Database1].dbo.[Table1] WHERE sharecode = 'KWV'  
                 (Remember that Table1 in this case is actually a view

3) If I create a Inline Table-Valued function called Table1() on ServerAB  that does a select against [ServerB].[Database1].dbo.[Table1] in exactly the same way as no 1 above ( SELECT *  FROM [LinkedServerB].[Database1].dbo.[Table1] with (nolock)) , then the following query takes sub-second to complete:
     SELECT *  FROM [ServerA].[Database1].dbo.[Table1]() WHERE sharecode = 'KWV'  
                 (Remember that Table1 in this case is actually a function)

Wrapping the function in a view has no effect on the speed of the view making the view again taking up to 50 seconds.

Other than re-developing the legacy applications or shipping data between these two databases I seem to have only two options:
A) Find a way to speed up the views
B) FInd a way to call inline table-valued function without have to use the paranthesis when calling them for example:
     SELECT *  FROM [ServerA].[Database1].dbo.[Table1] WHERE sharecode = 'KWV'  as opposed to
     SELECT *  FROM [ServerA].[Database1].dbo.[Table1]() WHERE sharecode = 'KWV'  

This will allow the legacy appliction to use the remote linked server data as if it resides in local tables.

I am willing to give the points for a solution to either A or B above.

Thanks

Gerhatd
       





Avatar of sandson
sandson
Flag of France image

Hello,

it seems that your view retrieves all data on ServerB prior to applying the where close. Can you display the execution plan to confirm that ?

It may also need an index on the sharecode column, try by adding an index on sharecode in the view Table1 on ServerA (look at this articled to create the indexed view : http://msdn.microsoft.com/en-us/library/aa215090(SQL.80).aspx)

regards,
Abdel
Avatar of dbit
dbit

ASKER

Yes, I've already looked at the execution plans for all the scenarios I described. Using a view definitely seem to bring back all the rows from the linked server.

There is already an primary key index on the table on the remote server on the sharecode.
Using the SQL profiler to look at the remote server instructions, I noticed that the bottleneck seem to be caused by the server calling sp_getschemalock:
     exec [sys].sp_getschemalock @p1 output,@p2 output,N'"TimeSeries"."dbo"."hi"'

I tried to get around this by specifying with (nolock) on the query statement in the view but that does not seem to help.
I ran a test on my servers using your second scenario (a view run a query against the remote server)
ServerA doesn't do anything for me. According to the execution plan it simply exec a remote query on ServerB by combining the where clause of the main query (ie. select * from Table1 where sharecode = 'KWV') with the view definition :
SELECT *  FROM [LinkedServerB].[Database1].dbo.[Table1] with (nolock)  WHERE sharecode = 'KWV'

So meaning that the optimizer understood my query and combined the view and the query to create a remote query to run on ServerB.

How did you linked ServeB to ServerA. Did you set it up as a 'SQL Server' server, thus allowing the SQL engine to use optimizations dedicated to SQL Server ?

regards,
Abdel
Avatar of dbit

ASKER

Yes, you are correct and I see exactly the same.
As I stated before, it seems to be the fact that the linked server are waiting for schema locks that creates the bottleneck.

In my case waiting for the schema locks take 99% of the time to execute on the linked server.
ASKER CERTIFIED SOLUTION
Avatar of sandson
sandson
Flag of France image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial