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 EXISTS
IN
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 TABLE
CREATE TABLE #ThisIsBetter
CREATE 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 UNCOMMITTED
READ COMMITTED
(which has two different meanings depending on database configuration)SNAPSHOT
(has special requirements)REPEATABLE READ
SERIALIZABLE
(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 ON
CREATE OR ALTER PROCEDURE #MyTempProcedure