SQL Server 2005 64bit query blocking - sql-server

We are experiencing some difficulties with SQL Server performance and wanted some help.
Our environment is: -
Windows 2003 Enterprise x64 Edition R2
Intel E5450 Quad Core 3ghz Processor
16GB RAM
SQL Server 2005 64bit Enterprise Edition (9.00.3282.00)
Database compatibility is 8 (but tested on 9 as well)
Hyperthreading is switched off
We have one database with a 1.2 million row table which is being queried (inefficiently), but is resulting in all 4 processors being saturated to the point where all other queries are blocked until the query is finished. This includes queries to separate databases and totally unrelated tables.
If the query is run with option MAXDOP 1 then all 4 cores run at 25% with the query taking 4 times as long, there is no blocking in this instance. In addition to this, we have run the same query on SQL 2000 and the response time is the same, but no CPU saturation.
We have a suspicion that the problem may be around contention over tempdb. In this particular instance we have a stored proc using a temp table and also the parallel query accessing the temp db I assume.
Obviously the standard response will be to re-write the queries. Firstly, this is not really a viable option and secondly this is only treating a symptom of the problem. Essentially the server is unable to process multiple requests, which is of great concern.
Does anyone know of any patches, config changes or known problems that might be causing this? Has anyone seen this before? Is it a 64bit nuance?
Regards
Lee

Sounds like the table isn't properly indexed. A table with 1.2 million rows shouldn't take anything to query. I've got tables with 60+ million rows and I query that table in milliseconds.
What's the query look like, and whats the table look like?

Sounds like locking on tempdb which effectively stops anything else that may use tempdb from running until it is finished. In particular it may be that the sysobjects table is locked.
The ideal step is to re-write the query to stop it locking tempdb for its entire duration, however, I'm guessing this is not easily possible.
You can try setting up a second instance of SQL to run this database. That way any temporary locking will only affect itself and not any other databases on the server.
To fix the problem for other queries running on the same database you can look into multiple files for the temp database.
However, once you're going this far for a solution you really need to go back to the problem query and try and make its footprint smaller. As Kristen commented, simply changing the way you create a temporary table can have a drastic effect on how things are locked.

Related

Queries slow when run by specific Windows account

Running SQL Server 2014 Express on our domain. We use Windows Authentication to log on. All queries are performed in stored procedures.
Now, the system runs fine for all our users - except one. When he logs on (using our software), all queries take around 10 times longer (e.g. 30 ms instead of 2 ms). The queries are identical, the database is the same, the network speed is the same, the operative system is the same, the SQL Server drivers are the same, connection pooling is the same, DNS is the same. Changing computer does not help. The problem seems to be linked to the account being used.
What on Earth may be the cause for this huge performance hit?
Please advise!
I would try rebuilding the SP (by running an ALTER statement that duplicates its existing structure) to force SQL Server to recompile. I don't know every way SQL Server caches things but it can definitely create distinct execution plans for different types of connections so I wouldn't be surprised if your slow user is running a version with an inefficient execution plan.
http://www.sommarskog.se/query-plan-mysteries.html

SQL Server Using TableDiff on large tables

We have a process which uses uses SQL Server's amazing tableDiff via:
Microsoft SQL Server\100\COM\Tablediff.exe
It's SQL Server 2008 R2. It connects from one instance to another identical instance. It works very well!
I have a situation where a table which now has 10767594 records is taking 2.5 hours to complete, it only has one table in the job. How can I improve this?
The process is triggered by a Windows Scheduled Task, this calls a .bat file, the .bat file contains the recommended code which has no issue. We have a couple of these in place and have had for some time. It's just the one job that deals with the big table from instance to instance that is taking too long.
I have realised that the source table does have an index but the destination table does not. I will put an index on this table, what else can I do?
Does table diff run better with indexes?
Is there a ways to use table diff more effectively?
E.g. if I capture the lastProcessedID can I run tableDiff next time for all records where id > lastProcessedID?
Any advice would be great. Thank you in advance
EDITED:
MY SOLUTION - This was a very very big surprise. As I mentioned above, the 10 million+ record table which was identical on the source and destination except for 2 indexes (on the source). After waiting for out of hours since this is an internal production server I applied the indexes to the source. Now I run the tableDiff job which has not been changed at all and it completes in under 2 minutes. 2.5 hours to 2 mins!
I have accepted the answer below because it very very helpful. I did go down the Merge Replication path however after setting up replication and publishing I found out that the production instance was not able to be a subscriber due to the replication not be ticked on install. As Jason says its a reasonable amount of research, learning and setting up. Since I am not a DBA and had not looked at this before it was a worth while experience.
The performance issue is because the remote queries pull every record from each place to do the comparison to generate the output. Indexes can help slightly to make the pull a little faster from each location, but it's not likely to be significant.
An incremental approach is definitely better. I don't believe tablediff directly supports comparing 2 queries. If it did, you could do something like EXCEPT or INTERSECT to do the comparisons. If you're trying to keep these databases in sync, why not consider other solutions, like log shipping, mirroring, SSIS, replication, clustering, etc.

SQL Server : TempDB high number of writes

We use a SQL Server 2008 Web Edition on a Windows 2012 R2 server (32 GB RAM) to store data for an ASP.NET based web application. There are several dabases with news tables and different views which we query regularly (SqlDataReader, Linq-to-SQL) with different joins and filter conditions. The queries itself are longer and domain-specific so I skip an example.
So far everything worked fine.
Now we had to change such a query and extend it with a simple OR condition.
The result was that the number of reads and writes in the TempDB increased dramatically. Dramatically means 1000 writes of more than 100 MB per minute which results in a total tempdb file size of currently 1.5 GB.
If we remove the OR filter statement from the original query the TempDB file I/O normalizes instantly.
However, we do not have a clue what's going on within the TempDB. We ran the Query Analyzer several times and compared the results but its index optimization recommendations were only related to other databases stats and did not have any effect.
How would you narrow down this issue? Does anyone else experienced such a behavior in the past? Is it likely to be a problem with the news query itself or is it possible that we simply have to change some TempDB database properties to improve its I/O performance, e.g. autogrowth?
Start by analyzing your execution plans and run your queries with statistics (use the profiler). The problem is not in de tempdb, but in your queries. Then you will see where you select to many row which are temporary saved in de tempdb. Then you can change the queries or add the index you are missing.

Two separate instances of SQL Server running a different explain plan

Here's one I need help from the SQL administrators out there. I have two separate SQL Server instances on Amazon EC2. One is our staging environment, and the other is our production environment, but they are configured exactly the same way (spawned from the same image).
We had a database that we copied from staging to our production environment last week. The way we copy a db to production is we take a backup of it on our staging site, and restore the backup in production. Anyways, we found that in production, one particular complex query was timing out after an hour, but that exact query in our staging environment completed in 10 minutes.
The explain plan on both were almost the same, except in one server it was doing a PK scan on a large table (8M rows), and on the other table it was doing an index seek. We're assuming this was the difference. So one server was doing a lot of disk IO, and the other was not.
So my question is, what are the reasons that one installation of SQL server would decide to use an index, while another one ignores it--assuming same versions of SQL server, and same data set? Even better, what are the best ways to find out why SQL is ignoring an index?
SQL Server uses statistics to determine the query execution plan.
Normally, they should be the same on the same datasets, but there is a chance of outdated statistics on one of the machines.
Use sp_updatestats to update statistics on both machines.
Also, I'm not familiar with Amazon EC2, but there may be a chance that the machines running the two instances have different number of CPU installed (or made available for use by SQL Server). This is also taken into account by the optimizer.
Parameter Sniffing?
An SP will use the query plan that was deemed most appropriate based on the parameters passed to it when it was executed (and so compiled) for the first time.
Restoring a database wipes the plan cache; if the SP on the copy of the database was run with parameters that favored an index seek, then that's what will subsequently be used.
You can check this by sp_recompile'ing both and running them again with identical parameters.
This was our mistake.
After much digging investigation, we found that one of our devs had added a couple additional indexes to the production db after the transfer. This was a case where the additional indexes actually caused the query optimizer to pick a less efficient route in the production environment.
Removing those additional indexes appeared to have addressed the performance issue for the particular query, and both explain plans are now the same.

Can SQL Server 2000 be made to populate a fulltext catalogue without blocking the tables it is reading?

I have a database server on SQL Server 2000 (yes I know...) with fulltext catalogues on some of its tables. I'm currently doing a full population overnight in quiet time, and I'd like to be able to update the catalogues during the day so that new data can be considered in searches.
The problem I've noticed is that when an incremental population runs there is a considerable amount of blocking, caused by the population process. The other transactions on this database are using "read uncommitted", or dirty reads, to minimize delays (I don't especially care about up-to-the-second accurate data) so I'm not exactly sure why the population, which itself is only reading data, blocks them.
Any clues, hints?
Short story: no, and the situation isn't much better until recent updates of SQL Server 2008. The RTM version of 2008 had these same issues, as we documented here:
http://www.brentozar.com/archive/2008/11/stackoverflows-sql-2008-fts-issue-solved/
The workaround is to use the fastest storage subsystems that make sense for your budget and your workloads. The full text catalogs need to be on separate arrays from your data and logs, and that way they can finish population faster.
You also mentioned that you're surprised that reading causes locks. We've got articles on SQLServerPedia explaining SQL Server's locking process, like this one:
http://sqlserverpedia.com/wiki/SQL_Server_Locking_Mechanism
If you want more specific answers, watch your server during the population. Run an sp_who2, look at which queries are being blocked, and run a DBCC INPUTBUFFER(spid) command to find out what their T-SQL is. That way you can see exactly what types of queries are causing it. If you're sure it's using read uncommitted, upload a copy of your query execution plan, and we can help interpret it to find out what's going on.

Resources