Slides are available at brobston.com.
Contact me with questions! Twitter: @AndrewBrobston
SJV & Associates is hiring full-stack .NET/SQL Server developers! Check out the listing at https://stackoverflow.com/jobs/280663/net-software-developer-sjv-associates.
I would have put the job listing in an iframe, but frame-ancestors 'self'.
SELECT, INSERT, UPDATE, and DELETE do.Whatever works for you.
WHERE and JOIN conditions.
SELECT a.Id, a.Whatever
FROM dbo.OurTable a
WHERE ISNULL(a.TextField, N'') = N''
(Besides that it's horribly contrived.)
SELECT a.Id, a.Whatever
FROM dbo.OurTable a
WHERE ISNULL(a.TextField, N'') = N''
dbo.OurTable has an index on TextField, we can't use it!But shouldn't SQL Server use the index to check for both NULL and N''?
SELECT a.Id, a.Whatever
FROM dbo.OurTable a
WHERE a.TextField IS NULL OR a.TextField = N''
-- Bad because a.TextField is NVARCHAR.
WHERE a.TextField = ''
-- Compare to NVARCHAR instead.
WHERE a.TextField = N''
Try to avoid explicit type conversions too.
One trick, when it's worth it: use a PERSISTED computed column in a temporary table to convert the value.
EXISTS and NOT EXISTSIN or NOT IN with a subquery?LEFT JOIN just to see if another table has a certain value?EXISTS and NOT EXISTS are right for you!I definitely made up that term. Maybe someone else has a better name.
-- Avoid:
SELECT a.Id, a.Whatever
FROM dbo.OurTable a
WHERE a.TextField IN (SELECT b.AnotherTextField
FROM dbo.AnotherTable b
WHERE b.Id = @SomeParameter)
-- NOT IN is even worse.
-- Also avoid:
SELECT a.Id, a.Whatever
FROM dbo.OurTable a
LEFT JOIN dbo.AnotherTable b ON a.TextField = b.AnotherTextField
WHERE b.AnotherTextField IS NOT NULL
-- Use EXISTS or NOT EXISTS:
SELECT a.Id, a.Whatever
FROM dbo.OurTable a
WHERE EXISTS (SELECT 1 FROM dbo.AnotherTable b
WHERE a.TextField = b.AnotherTextField
AND b.Id = @SomeParameter)
Don't use EXISTS or NOT EXISTS in the SELECT clause.
-- Avoid:
SELECT a.Id,
a.Whatever,
CASE WHEN EXISTS (SELECT 1 FROM dbo.AnotherTable b WHERE a.TextField = b.AnotherTextField) THEN 1
ELSE 0 END AS DontDoThis
FROM dbo.OurTable a
Workarounds can be difficult. Consider a LEFT JOIN to a subquery or CTE with GROUP BY.
DECLARE @DontDoThis TABLECREATE TABLE #ThisIsBetterCREATE FUNCTION statements.SELECT clause.STRING_SPLIT.JOIN rather than APPLY — do something besides use the function directly — consider it.One of the first things relational-database newcomers learn is ACID.
So that works for real-world SQL Server applications, right?
We can specify isolation levels in .NET (C#) application code asusing (var transaction = conn.BeginTransaction(IsolationLevel.ReadUncommitted))
or in SQL asSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.
READ UNCOMMITTEDREAD COMMITTED (which has two different meanings depending on database configuration)SNAPSHOT (has special requirements)REPEATABLE READSERIALIZABLE (has nothing to do with "forced serialization" from earlier)FROM dbo.OurTable a WITH (NOLOCK) on static tables when not guaranteed to be in READ UNCOMMITTED
EXISTS / NOT EXISTS outside the SELECT clause is an exception (it's a type of join).SET clause), window functions, and recursion when you have no better option.buffered: false, then .AsParallel().OrderBy(x => x.Whatever).ToList()FAST_FORWARD
usually, or STATIC with FORWARD_ONLY if you need unchanging results. (Look up these keywords if you need cursors.)WHILE can make sense in some situations, but ensure no batch or application solution is feasible.An execution plan results from SQL Server's compiling a query. You can look at execution plans and… learn things.
SHOWPLAN permissions on the databaseSET STATISTICS XML ONCREATE OR ALTER PROCEDURE #MyTempProcedure