Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-tenant SQL Server databases and parameter sniffing

I have a multi-tenant database in SQL Server 2012 where each tenant's rows are identified by a tenant_id column (aka the Shared Database, Shared Schema approach). Some tenants, particularly the newer ones, have very few rows, while others have many.

SQL Server's query optimizer normally builds a query plan based on the parameters provided during its first execution, then re-uses this plan for all future queries even if different parameters are provided. This is known as parameter sniffing.

The problem we have with our database is that SQL Server sometimes builds these plans based on parameters that point to a smaller tenant, which works fine for that tenant, but then when it reapplies the cached plan to a larger tenant it fails catastrophically (usually timing out, in fact). Typically we find out about this situation only when one of our larger tenants contacts us about experiencing time-out errors, then we have to get into the system and manually flush all the query plans to correct it.

There is a query hint you can use to prevent SQL Server from caching query plans (OPTIMIZE FOR UNKNOWN) but this results in some extra overhead since the query plan is being regenerated every time the query is called. An additional problem is that we're using Entity Framework which offers no ability to specify the OPTIMIZE FOR UNKNOWN hint on queries.

So the question is -- what is the best practice for multi-tenant databases with regard to parameter sniffing? Is there a way to disable parameter sniffing database-wide without having to specify it on every query? If so, is that even the best approach? Should I be partitioning the data in some other way? Is there some other approach I'm not thinking of?

like image 858
Mike Avatar asked Oct 19 '12 17:10

Mike


People also ask

What is SQL Server parameter sniffing?

SQL Server creates an optimal plan for a stored procedure by using the parameters that are passed the first time to the stored procedure is executed is called Parameter Sniffing.

What is multi tenant SQL Server?

Wikipedia defines multi-tenancy as "a software architecture in which a single instance of software runs on a server and serves multiple tenants." It means having a number of tenants (organizations, typically) all accessing a shared instance of the software, where they have the appearance that they are the only ones ...

What is parameter sniffing in mysql?

Parameter sniffing is the process whereby SQL Server creates an optimal plan for a stored procedure by using the calling parameters that are passed the first time a stored procedure is executed.


1 Answers

I have had similar problems, and have solved it successfully by passing my parameters in like this:

CREATE PROCEDURE [dbo].[InsertAPCheck]
@APBatchID  int = Null,
@BankAccountID  int = Null
AS
  /* copy parameters to temporary variables */
  SELECT @xAPBatchId = APBatchId, @xBankAccountID = @BankAccountID
 .
 .
 /* now run the meat of your logic using the temp variables */
 SELECT * FROM myTable where [email protected].

in other words, creating a local variable on a 1-1 basis for each parameter passed in and then only referencing those new variables within the logic of the SP. I am probably missing out on some optimization that SQL Server could do for me, but most importantly I miss out on the truly horrid performance I get when the param eter sniffing kicks in.

In your case, perhaps you could try doing this just for the multi-tenant id (which I assume is a parameter to all SP's?), and let SQL server optimize the rest of the parameters if it can.

like image 191
E.J. Brennan Avatar answered Nov 15 '22 06:11

E.J. Brennan