Results returned from a view using linked server may vary? - sql

i have a view that is using linked server to retrieve data from a remote server in SQL Server. On each time viewing the view, the results returned are vary. For example, 1st time execution may return 100 rows of records but on 2nd time of execution, rows returned are 120 rows. Any ideas what is the cause?

I have witnessed odd linked-server results that are a product of non-determinism written into the SQL itself, I.e. a TOP query written without an ORDER BY clause.
This problem, for example, where the chap had multiple non-unique foreign keys coming from a table source on the left hand side of a linked-server INNER JOIN, and wanted 10 rows from a remote sub-query to the right, where the end result was restricted to 10 rows itself, when it should have been greater than 10 rows.
Should definitely give your SQL a quick eye for such curiosities.

The data on the linked server changed between executions?

Is your SQL Server fully patched? SQL Server 2008 and 2005 both have bug fixes out related to incorrect query results from linked servers.
Here is one example:
969997 FIX: You receive an incorrect result when you query data from a linked server that is created by using an index OLE DB provider in SQL Server 2005 or in SQL Server 2008

Is the linked server also a SQL Server? If not, perhaps a buggy driver? I've seen odd results, for example, due to an old Informix ODBC driver. Are you able to run something akin to SQL Profiler on the linked server to see what command it's receiving?

I'm not sure what the answer is, but (assuming that your counts of 100 and 120 are accurate) can you not capture the data from the two runs and compare it? That might give you some clues as to what's going on. For example, is it completely different datat, or is it duplicate rows (in the 120 row batch).

Related

SSIS performance vs OpenQuery with Linked Server from SQL Server to Oracle

We have a linked server (OraOLEDB.Oracle) defined in the SQL Server environment. Oracle 12c, SQL Server 2016. There is also an Oracle client (64 bit) installed on SQL Server.
When retrieving data from Oracle (a simple query, getting all columns from a 3M row, fairly narrow table, with varchars, dates and integers), we are seeing the following performance numbers:
sqlplus: select from Oracle > OS File on the SQL Server itself
less than 2k rows/sec
SSMS: insert into a SQL Server table select from Oracle using OpenQuery (passthrough to Oracle, so remote execution)
less than 2k rows/sec
SQL Export/Import tool (in essence, SSIS): insert into a SQL Server table, using the OLEDB Oracle for source and OLEDB SQL Server for target
over 30k rows/second
Looking for ways to improve throughput using OpenQuery/OpenResultSet, to match SSIS throughput. There is probably some buffer/flag somewhere that allows to achieve the same?
Please advise...
Thank you!
--Alex
There is probably some buffer/flag somewhere that allows to achieve the same?
Probably looking for the FetchSize parameter
FetchSize - specifies the number of rows the provider will fetch at a
time (fetch array). It must be set on the basis of data size and the
response time of the network. If the value is set too high, then this
could result in more wait time during the execution of the query. If
the value is set too low, then this could result in many more round
trips to the database. Valid values are 1 to 429,496, and 296. The
default is 100.
eg
exec sp_addlinkedserver N'MyOracle', 'Oracle', 'ORAOLEDB.Oracle', N'//172.16.8.119/xe', N'FetchSize=2000', ''
See, eg https://blogs.msdn.microsoft.com/dbrowne/2013/10/02/creating-a-linked-server-for-oracle-in-64bit-sql-server/
I think there are many way to enhance the performance on the INSERT query, I suggest reading the following article to get more information about data loading performance.
The Data Loading Performance Guide
There are one method you can try which is minimizing the logging by using clustered index. check the link below for more information:
New update on minimal logging for SQL Server 2008

sql server - Openquery vs 4part name

A view that references a remote server
4part name ([ServerName], [DatabaseName], [Owner], [Object Name]
OpenQuery
Which is better performance?
Why is performance good?
AFAIK, it depends a lot on your remote server type.
With recent SQL version (2016) on both server (local and remote), I didn't noticed any difference.
If your remote server is anything else (postgres, mysql...) your really should use OpenQuery as it executes the query on the remote server, getting only the correct resultset. If you use the 4 part name, SQL server will order and filter on local.
For example, take a 4 million record table and execute a query like :
SELECT * FROM reoteserver.database.schema.table where id = 4
With openquery, sql server will get only the record with id 4. Without, it will get all the table, and then filter it to get the id 4.
Late to the party here, but the difference essentially is that 4 part queries are executed locally, thus cannot utilise indexes or keys since the local server doesn't know about them. Instead it essentially retrieves the entire object, then applies the filter. On a small table, you would be unlikely to notice a difference, but on a table with millions of rows, you'd notice a difference. Openquery essentially tells the remote server to execute the query on it's behalf then pass the result back.
General rule I would say is;
NEVER join on to a table using 4 part. Only join using Openquery and I would even avoid that where possible, but that's more of a personal preference.
However, 4 part SP execution i.e. EXEC ServerName.DBName.SchemaName.ObjectName is essentially the same since that also tells the remote server to execute the query on its behalf.

System.OutOfMemoryException when querying large SQL table

I've written a SQL query that looks like this:
SELECT * FROM MY_TABLE WHERE ID=123456789;
When I run it in the Query Analyzer in SQL Server Management Studio, the query never returns; instead, after about ten minutes, I get the following error: System.OutOfMemoryException
My server is Microsoft SQL Server (not sure what version).
SELECT * FROM MY_TABLE; -- return 44258086
SELECT * FROM MY_TABLE WHERE ID=123456789; -- return 5
The table has over forty million rows! However, I need to fetch five specific rows!
How can I work around this frustrating error?
Edit: The server suddenly started working fine for no discernable reason, but I'll leave this question open for anyone who wants to suggest troubleshooting steps for anyone else with this problem.
According to http://support.microsoft.com/kb/2874903:
This issue occurs because SSMS has insufficient memory to allocate for
large results.
Note SSMS is a 32-bit process. Therefore, it is limited to 2 GB of
memory.
The article suggests trying one of the following:
Output the results as text
Output the results to a file
Use sqlcmd
You may also want to check the server to see if it's in need of a service restart--perhaps it has gobbled up all the available memory?
Another suggestion would be to select a smaller subset of columns (if the table has many columns or includes large blob columns).
If you need specific data use an appropriate WHERE clause. Add more details if you are stuck with this.
Alternatively write a small application which operates using a cursor and does not try to load it completely into memory.

SQL Query - Finding Current log file usage for one database

I want to set up some monitoring software that will generate an SMNP trap if a database log file goes beyond about 95% usage. It can only look at the first result in the first column of an SQL query, so what I'm looking for is an SQL Query which will just return the percentage figure ONLY in the result - eg, 95
I've found several different ways of doing similar things, but all return table heading etc, whereas I just want the figure. It'll be running this query every hour so nothing too intensive. I'm running SQL version 8.
Thanks, Mike
You could write a query against the OS DMVs to get just the single value you're looking for.
Not sure if this will work for SQL Server 2000, but I know it works as far back as SQL Server 2005. It also requires that performance counters are enabled on the host server (i.e. OS, not just SQL Server).
This query should do the trick:
SELECT cntr_value as PercentUsed
FROM sys.dm_os_performance_counters
WHERE counter_name = 'Percent Log Used'
AND instance_name = 'your_database_name'

Excel query showing different result than SSMS query

I have had an odd error I cannot explain. Basically, I am running a query to my SQL database using excel and am having non-existent data pop up when it comes to a very particular order in my database.
Here is a simple query surrounding this order:
select * from OR200100 where OR200100.OR20001='0000793605'
Here is the output in EXCEL
And here is the same output in SQL
what is happening here? How could the same query generate 2 different results?
Run SQL Server Profiler against the database if you can, then compare the output to the sql query that you are running in ssms.
OK, so it's SQL Server then, that's important because different SQL products can have very different idiosyncrasies and controls.
The next things to check are these:
Is OR200100 a Table or a View? If it's a view then post it's code.
Are you using the same Login/account from both Excel and SSMS?
Are you sure that you are connecting to the same Server and Database? SSMS tells you what you are connected to, but client apps like Excel do not and it is very common for this type of problem to be caused by the app connecting to a Dev or QA version of the database. See here for some of the different ways that this can happen:
So I had a very similar problem, my query was grouping by week numbers. What I found was that one of the queries had set datefirst 5 set whilst the other didn't. I guess the key thing here is make sure, if you are using any SET operations in your ssms queries, these are identical to those in the Excel query string.