SQL 11 (Code Name: “Denali”) – Debugging enhancements – Setting, Labeling, Using & Searching Conditional Breakpoints


Way back in March 2011, I attended Tech-Ed India 2011 (read my 3 part series here – Part 01, Part 02, Part 03). During Tech-Ed, I learnt about some of the cool new T-SQL debugging enhancements in the next public release of Microsoft SQL Server, SQL 11 (Code Named: “Denali”). In the next couple of posts, I will attempt to summarize these enhancements, and finally provide a ranking of which features I liked best and would tend to use more often once Denali goes into production.

Why so late?

Some of you might be thinking – “Why is this guy posting this stuff so late? We are already in CTP03!” Well, the answer is simple – I believe in using a feature in practice before writing about it. Debuggers are a very powerful set of tools, and it would not be fair to write about something if I could not provide a few helpful tips & pointers.

As a  background, you may read my previous posts on T-SQL debugging:

It is important to remember that the SQL Server Management Studio for SQL 11 “Denali” is based on the Visual Studio 2010 shell. Hence, the debugging features of VS2010 “magically” flow into SSMS.

Debugging in Denali – Breakpoints

Test Script for this session

We will debug the following script in this session on SQL 11 (“Denali”) CTP03. It is a very simple script that loops through for 20 iterations.

DECLARE @iCounter INT = 0

WHILE (@iCounter <= 20)
BEGIN
    PRINT 'Hello World! The counter reads: ' + CAST(@iCounter AS VARCHAR(2))

    PRINT 'Hello Nakul! The counter reads: ' + CAST(@iCounter AS VARCHAR(2))

    SET @iCounter += 1
END
GO

Creating Conditional Breakpoints & Labeling them

One of the major features that was missing in the earlier versions of SSMS was the ability to have conditional breakpoints. In SSMS for Denali, conditional break-pointing is possible. To explore it’s features, let’s start debugging by pressing the F10 key as high-lighted in the Hands-On session. I would re-iterate that debugging in SSMS is not at all different than debugging in VS2010.

To demonstrate the fact, let’s place a breakpoint near the line for “Hello World!”. We will make this a conditional breakpoint, to break only if the value of the counter hits 10.

Hit F9 to setup the breakpoint on the desired line

Note that the information in the “Breakpoint” window is non-descriptive. Let’s correct that first

image
Right-click on the breakpoint, and choose “Edit Labels”

image 
In the “Edit Labels” window, type in a descriptive detail and click “Add”

If pre-existing, you can choose one if you like

image
On clicking “OK”, notice that the breakpoint can now be identified easily amongst a pile of breakpoints image
Now, right-click on the breakpoint and go to “Condition” image
Add the required expression as a condition and click “OK” image
Notice that in both the “Breakpoints” window &  editor window, the breakpoint symbol now has a little "plus (+) sign in it image
Let’s create a “Hit Count” based breakpoint for the second line image
For the test, let’s set this breakpoint to hit at intervals in multiples of 4 – at 4, 8, 12,16 & 20.

Hit OK once done to set the breakpoint

image
The Breakpoints window would look like the one in the screenshot image

Hit “Alt + F5” to run through the sample code. The first breakpoint hit will be “Hello Nakul!” when the hit count is 4. To verify whether the hit is correct or not, you can either use the “Locals” window or the “Immediate” window (Go to Debug –> Windows –> Immediate or press Ctrl+Alt+I):

image

Hit Alt+F5 again. The next breakpoint to be hit will again be “Hello Nakul!”. Hit Alt + F5 again, and we will hit the “Hello World!” breakpoint and so on.

Searching for specific breakpoints – using Labels to your advantage

Go to Debug->Windows->Breakpoints or press Ctrl+Alt+B to launch the Breakpoints window.

While we only have 2 breakpoints in this session and it is quite easy to remember them, in production code, there might be tens of breakpoints and it might be difficult to remember each one. What’s more, out of all breakpoints, you might want to work with only the breakpoints that are related to a particular operation – an update to a given table, for example.

In the breakpoints window, take the time out to label each breakpoint carefully. You may want to use your labels such that each label identifies a particular group of operations in question – for example, a label can be – “Updating Production”, “Updating Sales Orders” and so on.

Notice the addition of a “Search” box in the Breakpoint window. The “Search” box allows us to search on a specific column or on all visible columns of the breakpoint window.

image

Choosing “All Visible” in the “In Column” drop-down, let’s type in “World” in the “Search” box and hit Enter. Notice that SSMS will take the other breakpoints off the list. Clearing the search results will bring them back.

image

Concluding for today…

I believe that we have just barely scratched the surface of the debugging features available in SQL 11 (“DenaIi”). In my next post, I will cover how to Export & Import Breakpoints – a boon in collaborative development environment. After that, I will cover “Data Points”, which is in itself a very exciting development to the debugger.

Until we meet next time,

Be courteous. Drive responsibly.

Date Comparison – Dissecting BETWEEN – Use BETWEEN or comparison (greater than/less than) operators with equal to?


Whenever we talk about inclusive date comparison & filtering in T-SQL, the only two options that come to mind are the BETWEEN clause and the greater than (>) and less than (<) operators paired with the equal to operator. Today, let us attempt to find out if there is a difference between the two.

Let me mention that our study today will be restricted to dates only. DATETIME values need extra “precautions” on the part of the query developer to cover the time portion in the comparison. However, most legacy systems (and as we would see from the examples in the AdventureWorks2008R2 database), use separate storage for date and time values and therefore, the need to filter on the date value is a very realistic user scenario.

Dissecting BETWEEN

Without spending much time, let’s get right along to the simple test. Let’s assume that once a year, the Adventure Works Bicycle Company prepares a list of all employees who were hired in the organization 10 years ago, (because we are in 2011, this would be in 2001) to send out an organization-wide recognition of service notification. Quite simply, the query would be something like:

SELECT * FROM HumanResources.Employee
WHERE HireDate BETWEEN '2001-01-01' AND '2001-12-31'
GO

We get 2 records in return:

image

Now, let us study the actual execution plan to find out what goes on under the covers.

image

As it turns out, BETWEEN is internally implemented by pairing a set of comparison operators with the equal to operator!

Conclusion

We can safely conclude that BETWEEN is just a facade for the comparison operators. The only difference is in the fact that comparison operators, by themselves offer exclusive comparison (i.e. the comparison excludes the value being compared to). For an inclusive comparison, they need to be paired with the equal to (=) operator – something which the BETWEEN does out-of-the-box.

So is BETWEEN really required?

I studied the Books-On-Line pages for BETWEEN and the Comparison operators, and could not find any difference other than the one mentioned above (about BETWEEN being inclusive). So, the big question now becomes whether BETWEEN is really required? Wouldn’t our code be much better if we avoid the need for Microsoft SQL Server to transform the between into comparison operators?

Well, in my humble opinion, that’s where the issue is. We, as developers and ultimately, humans, tend to make mistakes. The compilers warn us of syntactical issues with our code, but there is nothing that would warn us about a logical bug. A single miss in placing an equal to operator (or placing of an operator in excess), might result in code that would be logically incorrect. Using BETWEEN when we need inclusive comparison just helps in avoiding such errors.

So, BETWEEN is required – it’s not mandatory, but recommended. And that’s why it’s a T-SQL coding best practice.

Interested in more such surprises?

If you are interested in more such surprises, please do check out my post on the differences between CAST & CONVERT here: http://beyondrelational.com/blogs/nakul/archive/2011/07/18/cast-v-s-convert-is-there-a-difference-as-far-as-sql-server-is-concerned-which-is-better.aspx.

Until we meet next time,

Be courteous. Drive responsibly.

SQL Server 2008/R2 & F1 – A Microsoft Case Study on how FILESTREAM can create a formula for performance, integrity & rob


Formula1 is the pinnacle of motorsports – a test of performance, integrity & robustness. The cars on the race track are technological marvels – they contain technologies that would build the cars of the future – technologies like KERS to harness braking energy for a power burst and DRS to reduce drag being the latest additions to the list this year.

I am a fan of the sport, but little did I know that the subject of my passion – Microsoft SQL Server – is closely associated to it.

A modern F1 car uses a lot of embedded electronics. It has an onboard Electronic Control Unit (ECU) that connects to 100+ onboard sensors which monitor and control critical operations like engine configurations, transmission, pit-lane communications and a lot more. As the car moves along the track at around 200miles per hour, it generates and transmits data to the engineers in the pit-garage at a rate of 100kilobytes to 0.5megabytes per second – totaling to about 2GB/race.

This streaming data is analyzed in almost real-time by the engineers who, with using historical data provide near instant analysis help shape the race strategy and ultimately lead a driver to become a World Champion and earn a Constructors trophy for a manufacturer.

The Case Study

Together with its technical partner Microsoft, McLaren Electronics is the official supplier of engine control units (ECUs) and associated data systems to all of the teams competing in the Fédération Internationale de L’Automobile Formula One World Championship annually between March and November.

Business Problem: “McLaren Electronics needed to replace file-based storage with a relational database for the more than 2 terabytes of engine control unit (ECU) data collected each year by a typical Formula One racing team.”

Solution:The company is using the FILESTREAM feature of Microsoft® SQL Server® 2008 to store ECU data in a relational database while providing rapid access to the data streams for users.”

How SQL Server helps analyze F1 Racing Data: http://www.microsoft.com/casestudies/Case_Study_Detail.aspx?CaseStudyID=4000001476

How SQL Server helps access huge data stores for F1 racing teams: http://www.microsoft.com/casestudies/Microsoft-SQL-Server-2008-R2-Enterprise/McLaren-Electronic-Systems/Firm-s-Solution-Accelerates-Access-to-Huge-Data-Stores-for-Formula-One-Race-Teams/4000009547

A brief video from Microsoft Showcase: http://www.microsoft.com/showcase/en/us/details/be728b1e-7f78-470f-be7e-4003b023ff1c

This week-end…

This week-end (September 09-11, 2011), when you enjoy the race at Monza in Italy (are you a Ferrari fan? If yes, this is your home race!), do not forget that deep inside the pit-garages are many instances of Microsoft SQL Server crunching huge amounts of data that help shape the race, and bring tomorrow’s technology on the road, today.

By the way, how many of you are coming over next month to the first ever Grand Prix of India at the Buddh International Circuit at Delhi, India?

Finally, remember that your road to/from work is not a Formula1 race-track. Until we meet next time,

Be courteous. Drive responsibly.

SQL Server Myth – Table Name cannot be same as Database Name


Microsoft SQL Server is home to many myths and legends, and I have developed an interest in knowing about them. It is really a very interesting exercise to know about these myths, and prove them incorrect if the situation permits.

The Myth

One such myth is that a table name in a Microsoft SQL Server database cannot be the same as the database name.

The application that I work on does not have such a scenario. I had never ever heard about anything remotely similar, and therefore, I had to investigate this one. So, let’s see if this one is true or not via a simple DIY ("Do It Yourself") test.

The DIY Test

I have always believed that a simple test can go a long way in clearing out the concepts. So, let’s begin by connecting to a SQL Server 2008 R2 instance, and checking if SQL Server allows us to create a table of the same name as a database.

/*
    WARNING - THIS CODE IS PRESENTED AS-IS AND WITHOUT WARRANTY.
              PLEASE DO NOT USE IT IN PRODUCTION/QA ENVIRONMENTS
*/
USE AdventureWorks2008R2
GO

CREATE TABLE AdventureWorks2008R2 (MyKey INT)
GO

Next, let’s insert a few values:

/*
    WARNING - THIS CODE IS PRESENTED AS-IS AND WITHOUT WARRANTY.
              PLEASE DO NOT USE IT IN PRODUCTION/QA ENVIRONMENTS
*/
USE AdventureWorks2008R2
GO
INSERT INTO AdventureWorks2008R2 VALUES (1), (2), (3)
GO

Finally let’s attempt to select from this new table followed by necessary cleanup:

/*
    WARNING - THIS CODE IS PRESENTED AS-IS AND WITHOUT WARRANTY.
              PLEASE DO NOT USE IT IN PRODUCTION/QA ENVIRONMENTS
*/
USE AdventureWorks2008R2
GO
SELECT * FROM AdventureWorks2008R2
GO

--Cleanup
DROP TABLE AdventureWorks2008R2
GO

Surprised? Don’t be. It’s perfectly legal to have a table name same as the database name.

So, what’s going on here?

Great question! That’s what one should be after.

A table is ultimately a database object. The database object name is referred to as its identifier. If we look into MSDN for the rules of naming identifiers (http://msdn.microsoft.com/en-us/library/ms175874.aspx), we see that the rules for naming database objects can be summarized as under:

  1. First character must be one of:
    • A Unicode letter (Latin characters from a-z, A-Z and characters from other languages)
    • The Underscore ("_"), at sign ("@") or the number sign ("#")
  2. Subsequent characters can be
    • Letters
    • Decimal numbers
    • Dollar sign ("$"), Number sign ("#") or underscore ("@")
  3. The identifier must not be a Transact-SQL reserved word. SQL Server reserves both the uppercase and lowercase versions of reserved words
  4. Embedded spaces or special characters are not allowed
  5. Supplementary characters are not allowed

Nowhere is it mentioned that identifiers cannot be the same as the database name.

NOTE: When identifier names conflict with reserved words, they must be enclosed in square braces. So, a table name like "TABLE" is illegal, while "[TABLE]" is perfectly legal.

Special Thanks to…

This post has been inspired from Pinal Dave’s (blog) series – SQL SERVER – Tips from the SQL Joes 2 Pros Development Series – Efficient Query Writing Strategy – Day 4 of 35

Until we meet next time,

Be courteous. Drive responsibly.

Performance Best practice – Transaction log must on a different drive. But WHY?


It is a well-known recommendation and best practice that the transaction log of any database must be on a drive different than the data files are on. This is especially useful to improve transaction log file performance, which manifests itself as a high value for the LOGBUFFER wait type. Refer Pinal’s post (blog) on the LOGBUFFER wait type here. Pinal has demonstrated this at multiple community meets (Tech Ed 2011, CTD – June 2011) and every time he performs the demo, the crowd erupts in admiration.

So, all’s well. But, the question that kept coming back to me was – WHY? Why does moving the transaction log to it’s own dedicated drive benefit the performance of the SQL Server?

To understand the WHY behind this best practice, it is imperative for us to understand the differences in the physical architecture of the transaction log and the data files.

SQL Server uses something called as a Write Ahead Log (WAL) mechanism. What this means is that even before data is persisted to the disk/data file, data is written to the transaction log. When data is written to a database, it moves from the memory (where the manipulation happened) to the transaction log. Later, when background check-pointing happens, this data is written from the log to the data file. Therefore, the data file performance does not directly affect the throughput of the database. The transaction throughput of the database ultimately depends upon the performance of the transaction log.

Since users can read or write any data from the data files, the read & write activity is essentially random in nature. Physically, the read-write heads inside of the disk are jumping around all over the place moving from one sector to another randomly – which slows down the drive, reducing the throughput.

The transaction log on the other hand, is written to serially. This is one of the reasons why instant file initialization cannot be used for transaction logs (refer Paul Randal’s post here), but that’s a different story. Because the transaction log is written to serially, and read from only during check-pointing, a log backup or a restart recovery, it is much more beneficial to place the transaction log on a drive that does not need it’s heads to move around randomly.

This is why moving the transaction log to it’s dedicated drive benefits the SQL Server performance wise.

You can read more on the physical architecture of the transaction log in Books On Line at: http://msdn.microsoft.com/en-us/library/ms179355.aspx

Now that I understand the reason why this arrangement works, I feel much more confident in implementing the same in my development, quality assurance and production environments.

Until we meet next time,

Be courteous. Drive responsibly.