Quantcast
Channel: T-SQL: Simplified CASE expression
Viewing all articles
Browse latest Browse all 43

Simplified CASE expression

$
0
0
Revision 4 posted to TechNet Articles by Saeid Hasani on 12/2/2013 1:27:37 AM

Introduction

SQL Server 2012 introduces these two new functions which simplify CASE expression:

  • Conditional function ( IIF)
  • Selection function ( CHOOSE )

Also we have been working with COALESCE, an old simplified CASE expression statement as NULL related statement prior SQL Server 2012. Although ISNULL is a function which logically simplifies a CASE expression, but it never translates to a CASE expression behind the scene (by execution plan). By the way, we will also cover ISNULL in this article, since it’s an alternative to COALESCE. The goal of this article is providing an in depth tutorial about these four statements:

  1. ISNULL
  2. COALESCE
  3. IIF
  4. CHOOSE

I use the term “statement” because although they do similar duty but they are not in same category by their purpose. For example ISNULL is a function while COALESCE is an expression.

As we will see later, the main purpose of introducing these statements are improving code readability and simplifying maintenance of code. But in some situations these statements usage will lead to poor performance. So we also will discuss about some alternative solutions.

This article targets newbies to advanced audiences. So if you are familiar with these statements, you can skip definition section.

Definition

ISNULL

Prototype 01

If expr_1 is null, then ISNULL function returns expr_2, otherwise returns expr_1. Following example shows its functionality.

Sample 001

Pic 001

If the data types of two arguments are different, if they areimplicitly convertible SQL Server converts one to the other, otherwise returns an error. Next sample execution leads to an error as illustrated in output figure.

Sample 002

Pic 002

Whereas by changing the value of the variable @Val_2 to ‘500’, because this value is convertible to numeric data type INT, we do not encounter any error. Following code demonstrate this:  

Sample 003

Pic 003

Implicit conversion in ISNULL function also could lead to truncate value, if the length of expr_1 data typeis smaller than length of expr_2 data type. So it’s safer to convert explicitly if needed. In next example first SELECT list column suffers from value truncation while second will not.

Sample 004

Pic 004

Determine output data type

The next code illustrates the rules to determine output data type:

Sample 005

Pic 005

Determine output NULL-ability

The next code illustrates the rules to determine output data type:

Sample 006

Pic 006

COALESCE 

Prototype 02

COALESCE returns the first NOT NULL expr in the expression list. It needs at least two expressions.

Dissimilar from ISNULL function, COALESCE is not a function, rather it’s an expression. COALESCE always translates to CASE expression. For example,

COALESCE (expr_1, expr_2)

is equivalent to:

CASE

WHEN (expr_1 IS NOT NULL) THEN (expr_1)

ELSE (expr_2)

END

Therefore the database engine handles it like handling CASE expression. So this is in our simplified CASE expression list.

Following code is one of many samples that could illustrate different execution plans for COALESCE and ISNULL:

Sample 007

Pic 007

Every single rule that operates for CASE expressions also is applied to COALESCE. So we do not have the limitations that discussed about ISNULL function, neither about output data type nor output column NULL-ability. Even there is not suffering from value truncation. To illustrate these points, next example is the new revision of former examples that was provided for ISNULL, but replace with COALESCE:

Sample 008

Pic 008

IIF

Prototype 03

IIF is a logical function which introduced in SQL Server 2012. It’s like conditional operator in C-Sharp language. If condition is true, x evaluated, else y evaluated. Following example illustrates this:

Sample 009

Pic 009

Like COALESCE expression, IIF function always translates to CASE expression. For instance,

IIF ( condition, true_value, false_value )

is equivalent to:

Case

when  (condition is true) then (true_value)

Else (false_value)

End

This example shows that this translation.

Sample 010

Pic 010

CHOOSE 

Prototype 04

CHOOSE is a selection function which introduced in SQL Server 2012. It’s like switch operator in C-Sharp language. If index (must be convertible to data type INT) is NULL or its value is not found, output will be NULL. This function needs at least two arguments, one for index and other for value. Following code illustrates this:

Sample 011

Pic 011

Like COALESCE expression and IIF function, CHOOSE also always translates to CASE expression. For example,

CHOOSE ( index, val_1, val_2 )

is equivalent to:

Case

when  (index = 1) then val_1

when  (index = 2) then val_2

Else NULL

End

This simple code shows that this translation.

Sample 012

Pic 012

Performance

Although the main purpose of simplified CASE expression statements is increasing readability and having cleaner codes, but one important question is how these statements impact on the database performance. Does any performance different between CASE expression and these statements? In this path we will be noticed that to achieve best performance it’s usually better to find alternative solutions to avoid using CASE and these statements.

Dynamic filtering

This is common to write reports and searches which accept input parameters. To achieve better performance it’s a good practice to write their code within stored procedures, because procedures store the way of their executing as an execution plan and reuse it again. By the way, there are some popular solutions to do this.

IS NULL and OR

This is the most common solution. Let me start with an example and rewrite it with comparable solutions:

Sample 013

Pic 013

The main problem here as illustrated in above figure is using same execution plan for all three situation. It’s obvious that third one suffers from an inefficient execution plan.

CASE

We can change the combination of IS NULL and OR and translate it using CASE for conditions in WHERE clause. Now we rewrite above code like this one:

Sample 014

Pic 014

Using CASE shows improvements to IS NULL and OR, but with more CPU cost for first one. Also the Reads and Actual Rows decreased in first two executions. So it’s better but still we continue this experiment.

COALESCE

We can change CASE and translate it to COALESCE for conditions in WHERE clause. Now we rewrite above code like this:

Sample 015

Pic 015

It’s obvious that because COALESCE translates to CASE internally, so there is no different between them.

ISNULL

Now we rewrite above code and use ISNULL instead of COALESCE:

Sample 016

Pic 016

There is no difference in Durations, but with more estimated rows.

Dynamic SQL

Using above four solutions we never achieve better performance, because we need different efficient execution plans for each combination of input parameters. So it’s time to use alternative solution to overcome this problem.

Sample 017

Pic 017

There is no doubt that this solution is the best one!

You can find more information about last solution in Erland website.

Concatenate values in one column

This is another common problem that fits to our discussion. In this example we just cover COALESCE and ISNULL solutions and at last we will see an alternative solution which performs better than using the CASE solutions.

COALESCE

Next code concatenates the values of column “ProductID” and delimited each with comma separator.

Sample 018

Pic 018

This code executed in 13 seconds in our test system.

ISNULL

Now we rewrite above code and use ISNULL instead of COALESCE:

Sample 019

Pic 019                                                                        

The duration decreased to 3 seconds.

XML

It’s time to use alternative solution to overcome this problem.

Sample 020

Pic 020

The duration decreased to 21 milliseconds.

There is no doubt that this solution is the best one. But because using XML, this solution has some limitations related to some special characters.  

Branch program execution based on switch between possible values

This is so common to use CHOOSE function to write cleaner codes. But is it the best solution to achieve optimal performance? In this section we discuss about this question.

CHOOSE

Let’s start with an example that uses CHOOSE as its solution.

Sample 021

Pic 021

This code executed in 352 millisecondsin our test system.

UDF function

Now we rewrite above code and use a Table Valued Function to produce CHOOSE list:

Sample 022

Pic 022                                                                        

The duration decreased to 195 milliseconds.

Permanent Lookup Table

It’s time to use alternative solution to overcome this problem.

Sample 023

Pic 023

The duration decreased to 21 milliseconds.

There is no doubt that this solution is the best one. By increasing the number of values in parameter list of CHOOSE function, the performance decreases. So by using permanent lockup table that benefits from physical index we can achieve the best performance.

More Readability

Conclusion

See Also 

Tags: sq server, en-US. has comment

Viewing all articles
Browse latest Browse all 43

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>