Would the following SQL Statements be the cause of a deadlock? - sql-server

I'm looking for a way to explain a deadlocking issue. I think I know what is causing it, but I'm not sure of the exact events.
We have a long-running view (several seconds). We are updating one of the tables that is used in that view. The updates can also take several seconds. The update statements that are running when the deadlock error is thrown join to the view. For example:
UPDATE t1 SET
Field1 = 'someValue'
FROM Table1 t1
JOIN TheView v ON v.TableId = t1.TableId
WHERE v.Condition = 'TheCondition'
The statement that appears to be getting shut down due to the deadlock is like:
SELECT * FROM TheView
Where the view is defined as:
CREATE VIEW TheView AS
SELECT *
FROM Table1 t1
JOIN Table2 t2 ON t2.foo = t1.foo
I'm pretty sure that the deadlock is occurring because both the view and the update statement depend on Table1. Is this scenario possible?
Thanks

Have you tried using SQL Profiler? Profiler will tell you exactly what statements are involved in a deadlock and include the resources each process has locked that the other process needs etc.

Is it possible? Sure. You'll need to do some work to find out for sure. See: How to Track Down Deadlocks Using SQL Server 2005 Profiler

It is definitely possible. I posted several similar repro scripts here: Reproducing deadlocks involving only one table
One way around is to use snapshot isolation.

Related

Creating SQL Server trigger to debug database issue

I have a database where one of the columns in one table keeps going blank. There's nothing in our software that can clear that column, so we are quite perplexed how it keeps happening.
Any suggestions on how I can figure this out? I'm thinking of creating a trigger that runs every time this table gets updated, and ideally when that field becomes empty.
But what kind of info can I actually track that will help me figure this out? Can I store the SQL statement that gets run when that update occurs? Can I store the Windows process that is connected to the database?
Any other suggestions? Thanks
You could also throw an error from trigger and have your client fail. If your client code is written to handle errors and log them, you can find out what causes the issue that way.
One thing you can try is using a trigger and testing for the specific column being updated with if update(column).
You can then capture some diagnositc data such as the following into a logging table:
select ##Spid, r.plan_handle, p.program_name, p.loginame, b.event_info
from sys.dm_exec_requests r
join sys.sysprocesses p on p.spid=r.session_id
cross apply sys.dm_exec_input_buffer(r.session_id, r.request_id)b
where session_id=##Spid
Something like this may work, if you create the correct set of columns in some kind of logging table:
IF EXISTS (SELECT 1 FROM inserted WHERE LEN(ProblemColumn) = 0)
BEGIN
INSERT INTO dbo.SomeLoggingTable(cols)
SELECT getdate(), i.key, buf.*
FROM inserted AS i
CROSS APPLY sys.dm_exec_input_buffer(##SPID, NULL)
WHERE LEN(ProblemColumn) = 0;
END

SQL Server Linked Server Update - terrible performance

In my SQL Server 2012 database, I have a linked server reference to a second SQL Server database that I need to pull records from and update accordingly.
I have the following update statement that I am trying to run:
UPDATE
Linked_Tbl
SET
Transferred = 1
FROM
MyLinkedServer.dbo.MyTable Linked_Tbl
JOIN
MyTable Local_Tbl ON Local_Tbl.LinkedId = Linked_Tbl.Id
JOIN
MyOtherTable Local_Tbl2 ON Local_Tbl.LocalId = Local_Tbl2.LocalId
Which I had to stop after an hour of running as it was still executing.
I've read online and found solutions stating that the best solution is to create a stored procedure on the Linked Server itself to execute the update statement rather than run it over the wire.
The problems I have are:
I don't have the ability to create any procedures on the other server.
Even if I could create that procedure, I would need to pass through all the Ids to the stored procedure for the update and I'm not sure how to do that efficiently with thousands of Ids (this, obviously, is the smaller of the issues, though since I can't create that procedure in the first place).
I'm hoping there are other solutions people may have managed to come up with given that it's often the case you don't have permissions to make changes to a different server.
Any ideas??
I am not sure, whether it can give more performance, you an try:
UPDATE
Linked_Tbl
SET
Transferred = 1
FROM OPENDATASOURCE([MyLinkedServer],'select Id, LocalId,Transferred from remotedb.dbo.MyTable') AS Linked_Tbl
JOIN MyTable Local_Tbl
ON Local_Tbl.LinkedId = Linked_Tbl.Id
JOIN MyOtherTable Local_Tbl2
ON Local_Tbl.LocalId = Local_Tbl2.LocalId

How to check blocking queries in SQL Server

I have one warehouse server which got data/sync from legacy system 24/7, I noticed some of my reports/sql jobs performance is uncertain and most of the time I heard from DBA team that my query is blocking to other sync process.
From DBA team I came to know command i.e. EXEC SP_WHO2 by which I can identify spid of query which cause blocking by looking into column BlkBy.
Please suggest me how I can avoid blocking and other ways to check blocking in SQL Server
Apart from Sp_Who2 you can use following query to identify blocking in you SQL.
SELECT
db.name DBName,
tl.request_session_id,
wt.blocking_session_id,
OBJECT_NAME(p.OBJECT_ID) BlockedObjectName,
tl.resource_type,
h1.TEXT AS RequestingText,
h2.TEXT AS BlockingTest,
tl.request_mode
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id
INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
GO
Also can check detail of particular SPID by using following command.
DBCC INPUTBUFFER(56) — Will give you the Event Info.
KILL 56 -- Will kill the session of this id.
This is a very comprehensive guide. Some basic guidelines though:
Avoid SELECT ... INTO #temp pattern and instead create a table first and use INSERT INTO #Temp SELECT...
Use WITH (NOLOCK) on queries where you can tolerate dirty reads
Ensure proper indexes exist
Use sargable predicates in your WHERE clauses
Talk to your DBA about potentially enabling READ_COMMITTED_SNAPSHOT isolation level
The simplest method is by using the Activity Monitor query within Microsoft’s SQL Server Management Studio (SSMS). To access this query from SSMS: first open up the main window; then click ‘Activity Monitor’ under ‘Tools’; then use either the ‘Processes/Sessions’ tab or specifically select ‘Blocking Processes” from the drop down menu at top left of the monitor window. This will show all currently running processes and their associated session ID's, as well as any transactions they might be involved with such as those that are being blocked by other threads.
You can also check for blocking using a few T-SQL scripts designed explicitly to check locking behavior on working systems. One such script is called SP_WHO2 this simple system-stored procedure displays lock information about active user connections and associated process IDs against all databases running on an instance of SQL server. --Cheers Mike B

Why the Informix database, change my original SQL code after creating a view?

Hi and thanks in advance.
I would like to know why my code got changed after i create a new view, this happend with two different IDE, Server Studio and RazorSQL, this is an example.
Original Code:
SELECT T_USER.ID IDUSER, T_DEP.DESCRIPTION DEPARTMENT
FROM TABLE1 T_USER
INNER JOIN TABLE2 T_DEP ON TABLE2.ID = TABLE1.ID
After create a view
DROP
VIEW orales:vw_test;
CREATE
view "owner".vw_test (id, description) as
SELECT
x0.id
x1.description ,
FROM
("owner".table1 x0 JOIN "owner".table2 x1
ON
((x1.id = x0.id)));
I want to know how to prevent the compiler or something overwrite the name of my tables's alias and the clause of my inner join.
Thank you again :)
You can't prevent this behaviour.
Actually, all databases do this. Your raw query is parsed into an abstract syntax tree which is stored in the database in a proprietary format.
What you are seeing is the rendering of that AST as a valid SQL statement.
Your original query is long gone.
You shouldn't be relying on the database to "manage" the source for your queries. Your original query is "code" and should be managed by a version control system, just like all your other code in your project should be. Doing so means the internal representation of your query in the database is irrelevant, and of course gives you all the other benefits of a VCS.

Stored Procedure for Updating a Column in Sql Server

I have a requirement to update a column with multiple values. The query looks like below.
Update table1 set column1 = (
select value from table2 where table1.column0 = table2.coulmn
)
Is there any generalised stored procedure for a requirement like the above?
short of creating a statement as a string and using the "execute" statement, I don't know of one. Generally "execute" is frowned on as it's a potential injection attack point.
Why would you want to update one table with information that is easily available in another? Seems like you are just guaranteeing that you are going to have to run this query every single time you perform an update, insert or delete against the camsnav table. Otherwise how are you going to keep them in sync?
Also, if you cannot guarantee that the sub-query will return exactly one row, it is probably safer to use the SQL Server-specific and proprietary update format:
UPDATE f SET nav = n.nav
FROM camsfolio AS f
INNER JOIN camsnav AS n
ON f.schcode = n.schcode;
SQL Server doesn't use "generalised stored procedures" for this kind of thing. It's up to you to build your own SP, composed using an appropriate parameterized UPDATE statement.

Resources