10 dos and 10 don’ts for the sql server clr matt whitfield

36
10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

Upload: vivian-mckinney

Post on 05-Jan-2016

220 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

10 DOs and 10 DON’Ts for the SQL Server CLR

Matt Whitfield

Page 2: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

Who am I?

• A geek, mostly• I hang about on

ask.sqlservercentral.com• I provide (now free-of-charge)

SQL Server tools• I help run the #SQLSoton user

group• I work for a small company in

Southampton

Page 3: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

What’s this presentation about?

• The CLR is a hugely untapped resource in SQL Server

• I’m on a bit of a mission to make people more aware of what you can do and how you can do it best

• This presentation addresses the ‘how you can do it best’ bit…

…at a ‘starter’ level

Page 4: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

So what is the CLR anyway?

• CLR = Common Language Runtime

• In the SQL Server world, we use the term CLR to refer to database objects that are implemented in a CLR language (C#, VB.NET …)

• We can make procedures, functions, user-defined types, user-defined aggergates and triggers

Page 5: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #1:Know your transactions

• The easiest way to wrap your transactions in the CLR is using the TransactionScope() class

• If you are just using a single connection, then a local transaction will be issued

• However, if you connect using a different connection string (even in the same database) a distributed transaction will be enlisted

Page 6: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #1:Add strings together

• Basic concept in all .NET code

• string is Immutable– An instance of a string cannot be changed– Special compiler support for strings can make

it look like you can change it

• Adding strings together places load on the managed heap and garbage collector

• Use StringBuilder instead

Page 7: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #2:Know structs v classes

• In .NET, there are two types of object– Reference types– Value types

• Reference types are passed around by their reference – functions will operate on the same object

• Value types are passed around in their entirety – functions will operate on a copy of the object

Page 8: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #2:Know structs v classes

• What does that mean?

DEMO TIME

Any volunteers?

Page 9: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #2:Go overboard

• The CLR support in SQL Server is a great programming tool

• It allows you to perform an extremely wide variety of operations

• It also, therefore, allows you to do dumb stuff

• Don’t start trying to implement all your procedures in CLR for the sake of it

Page 10: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #2:Go overboard

• Don’t wrap your T-SQL in a CLR procedure that just passes that T-SQL back to the engine (i.e. don’t make CRUD procedures in the CLR)

• Don’t create CLR types when they don’t really add value to the task at hand – remember there is an overhead

Page 11: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #3:Dispose your IDisposables

• If an object implements IDisposable, then it expects you to call Dispose() on it when you are finished

• The idea is that Dispose() gives the object the chance to release unmanaged resources early – before garbage collection

• You don’t necessarily know why an object is IDisposable, so you need to trust that it is necessary

• There is huge misconception about this

Page 12: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #3:Dispose your IDisposables

• The easiest way to guarantee disposal is through the using() {} block.

• When you exit the scope of a using block, the resource that you allocated in that block is guaranteed to be disposed, no matter how you exit the block (Exception, return)

• You can find incorrect examples of this all over the web, MSDN included

Page 13: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #3:Dispose your IDisposables

DEMO TIME

Page 14: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #3:Forget that data scales

• Data is often bigger in your production environment than in your test environment

• Don’t implement anything that assumes a fixed size of data (e.g. a static array without bounds checking)

• Don’t assume that an access method that is fastest with a small amount of data will be fastest with a large amount of data

Page 15: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #4:Aim to write SAFE code

• Permission sets control what your CLR code can do

• SAFE is a restrictive permission set, but targeting it means that you cannot affect the stability of the SQL Server Process

• EXTERNAL_ACCESS allows access to resources outside of SQL Server, but be careful not to introduce unnecessary waits

• Web service call in a trigger – I’m looking right at you

Page 16: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #4:Aim to write SAFE code

• UNSAFE is called unsafe for a reason.

• You need to be very sure about what you are doing under the UNSAFE permission set.

• How long will that static variable live for?

• What exactly is happening when another thread is started?

Page 17: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #4:Treat NULL as an afterthought

• NULLs happen• Always assume that you will receive a NULL

value as a parameter or in data that you read back from the database

• Use nullable types to wrap simple types in your data structures if you need to

• The Sqlxxx types all represent NULL with the IsNull property

• Nullable types represent NULL with the HasValue property

Page 18: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #5:Understand the GAC-lack

• Only ‘blessed’ assemblies can be loaded from the GAC

• Other assemblies need to be loaded through CREATE ASSEMBLY

• This can create a maintenance issue if application layer code shares an assembly with the database layer code

Page 19: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #5:Understand the GAC-lack

• Mscorlib.dll• System.Data.dll• System.dll• System.Xml.dll• System.Security.dll• System.Web.Services.dll• System.Data.SqlXml.dll• System.Transactions.dll• System.Configuration.dll

• Microsoft.VisualBasic.dll• Microsoft.VisualC.dll• CustomMarshalers.dll• System.Data.OracleClient.dll

Page 20: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #5:Use finalisers

• Finalisers are the .NET equivalent of destructors – code which is fired when an object is freed.

• In .NET, garbage collection does the free, and so calls your finaliser for you

• This means that your class is always promoted to a Generation 1 collection…

• What on earth is that?

Page 21: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #5:Use finalisers

• Garbage collection is done in generations 0, 1 and 2

• Generation 0 is the cheapest, implying the least work for the garbage collector

• A ‘dead’ object with a finaliser is always skipped – guaranteeing promotion to Generation 1

• All objects referenced by the object with the finaliser are also kept alive

Page 22: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #6:Understand managed memory

• Managed memory isn’t the same as Native memory

• The managed memory used by the CLR comes from the MemToLeave address space

• Moving objects between native and managed memory is called marshalling, and it has a cost associated with it

Page 23: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #6:Reinvent the wheel

• Does your boss like the ‘Just Do It’ attitude?

• It works for Nike, for coding not so much

• Take the time to find out if the function you want already exists (it probably does)

• If you can’t find it, try community sites – they are immensely helpful

Page 24: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #7:Use the context connection

• If you need to get data from the database that your code is running against…

…use the context connection

• Connection string is:

“context connection=true;”

• Connecting using a standard connection requires elevation to EXTERNAL_ACCESS

Page 25: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #7:Access data in scalar functions

• CLR Scalar Functions can be a lot faster than their T-SQL equivalents, particularly for string manipulations and complex procedural logic

• Accessing data in scalar functions is not cool

• You will absolutely kill performance by setting up a connection, running a query, returning the result

Page 26: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #8:Write efficient code

• If you are running CLR code in SQL Server, then you are running it in the place within your architecture that is hardest to scale

• It might be easy to write a brute-force algorithm, but when will it become a problem?

• When you’re on holiday – and you certainly don’t want to spend the time on re-writing the algorithm to be more efficient then

• Put your code in a normal app to profile it

Page 27: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #8:Over optimise

• Hang on… didn’t you just say to write efficient code?

• Yes, but there’s a difference between efficient and unintelligible

• Simple, well structured code often has suitable performance characteristics

• Don’t spend 90% of the time on the last 10% performance gain

• Find and solve the major bottlenecks first

Page 28: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #9:Understand boxing

• No, not the sport, or the day after christmas

• We learned about value and reference types earlier

• All objects can be treated the same way

• So how is a value type passed in a context that expects a reference (e.g. List<T>)

• Boxing

Page 29: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #9:Understand boxing

• Boxing is taking your value type, and enclosing it in an Object instance, so it becomes a reference type

• This has implications for equality

• 1 == 1, but (object)1 != (object)1

• Why?

• Because when boxed, each 1 has it’s own box & reference, and these are not equal

Page 30: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #9:Move the middle tier in

• We’ve established that sometimes it can be useful to run middle tier code in the database

• This should not be a default position

• Running middle tier code in the database will limit your ability to scale-out – scaling out the database layer is inherently more complex than scaling out a middle tier.

Page 31: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #10:Use Dictionary<TKey, TValue>

• Dictionary objects allow fast (close to O(1)) access to a large list of objects

• Finding an object by key rather than looping through is the exact equivalent of doing an index seek rather than a scan

• When implementing objects for dictionary access, over-ride the GetHashCode and Equals methods of Object

Page 32: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DO #10:Use Dictionary<TKey, TValue>

• Be careful, though

• If two objects would return true when Equals was called between them, then their GetHashCode calls must return the same value

• This makes it unsuitable for fuzzy matching (e.g. allowing tolerance between float values)

Page 33: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’T #10:Call Environment.Exit

• So Mladen Prajdic told me I should put this in. I think he was joking but…

• This shows some of the dangers of working in the UNSAFE permission set

• What happens when you call Environment.Exit?

• It exits your procedure and rolls back?

Page 34: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DOs:

• Know your transactions• Understand structs & classes• Dispose your IDisposables• Aim to write SAFE code• Understand the GAC• Understand managed memory• Use the context connection• Write efficient code• Understand boxing• Use Dictionary objects

Page 35: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

DON’Ts:

• Add strings together• Go overboard• Forget that data scales• Treat NULL as an afterthought• Use finalisers• Re-invent the wheel• Access data in scalar functions• Over-optimise• Move the middle tier in• Call Environment.Exit

Page 36: 10 DOs and 10 DON’Ts for the SQL Server CLR Matt Whitfield

Thanks!

• Any questions – drop me an email:

[email protected]

@atlantis_uk on twitter

• If you live near Southampton – come to the #SQLSoton user group

• If not – find your local user group at Community corner