Press "Enter" to skip to content

Category: T-SQL

Working in Batches in SQL Server

John Deardurff has some advice:

I’ve been reviewing Azure SQL Database performance guidance recently and came across Microsoft’s documentation on How to Use Batching to Improve Application Performance. While the article focuses on Azure SQL Database, the same principles of batching transactions for better performance apply equally well to SQL Server and Azure SQL Managed Instance.

The reason this topic caught my attention is that batching doesn’t just improve performance. It can reduce blocking, minimize rollback pain, improve transaction log efficiency, and potentially lower costs in cloud environments. That’s a pretty good return on investment for a relatively simple coding change. Here is the SQL Script that I use for this demonstration. Feel free to test for yourself. (It is a text file, so you will have to save it as a .sql file.)

Batching is especially important on delete operations against larger tables, where you don’t remove enough data to make TRUNCATE TABLE a viable alternative (or where you don’t have permissions to truncate). But one thing to keep in mind is that index design matters for batch operations. If you don’t have a good index, your first batches will be fast but they will gradually slow down as SQL Server needs to scan an increasingly large range to find the next set of rows to update. I wrote about this quite a while ago when putting together a talk on near-zero downtime T-SQL operations.

1 Comment

Playing Poker in T-SQL

Brent Ozar is a madman and I love it:

Wanna play some Texas Hold ‘Em style poker and make a pile of Query Bucks? Wanna watch other database people playing?

Click through to learn more about the game itself, but also the strategic choices Brent made and a bit of an after-action report on what it took to generate this code.

Also, shout out to Brad Shultz, whose blog I miss. It was his T-SQL Tuesday on the APPLY operator that really opened my eyes to how good that operator is.

Finally, I’m giving this post the most coveted tag in Curated SQL: Wacky Ideas. It’s rare that I get to use this one.

Leave a Comment

Surrogate Keys in Fabric Data Warehouse

Louis Davidson does some more digging:

Creating the simplest of tables, the first thing I start thinking about is making sure that the data is going to be protected from the user. Users (including myself on my own projects when I have my user hat on) don’t notice when they start inserting poor quality data sometimes. Oops, I hit F5 twice, I wonder if that will affect my data? Without proper constraints, it probably will.

In this second entry, I want to cover a few things about handling surrogate values that will help you avoid some of the (in retrospect) kind of dumb expectations that I had. Fabric Data Warehouse T-SQL feels so much like SQL Server Relational T-SQL that some stuff like choosing a surrogate key makes me think I am missing something.

One of the things Louis mentions is how the values get inserted and how it looks like they’re in different ranges. This makes sense, as each distributed node likely has its own range of identity values, similar to the way merge replication would work with identity keys to prevent overlap.

Leave a Comment

Scripting SQL Agent Job Creation Scripts

Aaron Bertrand sees that it’s all funhouse mirrors:

On this site, we usually talk about SQL Server performance problems that involve execution plans, locking, indexes, and waits. But SQL Server Agent can determine when backups, maintenance, ETL, monitoring, and reporting all arrive at the instance. In a way, a job deployment script is part of your performance configuration: you can materially impact the workload if you accidentally share a schedule across too many jobs.

I often create jobs in test environments that will later get distributed to many servers, often in isolated environments that can’t see each other. Creating an idempotent script to create a job, but only if it doesn’t already exist, can be cumbersome to get right. Many will prefer to use DbaTools Copy-DbaAgentJob, and that can be a great option if your deployment mechanism is PowerShell, DbaTools is already entrenched in your environment, and you can run the script from a place that can see the other server. In our case, T-SQL scripts are often passed on to colleagues or automation to be run independently in a different environment. Apologies to friends of SSMS, but the default right-click > Script Job output leaves a lot to be desired:

Click through for a variety of problems that the scripting logic has, as well as the solution Aaron came up with.

Leave a Comment

Replacing REPLACE()s with TRANSLATE() in SQL Server

Greg Low makes use of an uncommon function:

If your T-SQL is buried under layers of nested REPLACE() calls just to swap out a few characters, there’s a simpler way. SQL Server’s TRANSLATE() function — introduced in 2017 but still rarely used — lets you replace multiple characters in a single string with one function call instead of stacking several REPLACE() functions inside each other.

This guide covers how TRANSLATE() works, how it compares to REPLACE(), and where it falls short compared to other SQL dialects like PostgreSQL and Oracle.

One important thing to remember with TRANSLATE() is that it’s a character-for-character replacement. In other words, if you TRANSLATE('ABCDEFG', 'x'), it will replace every instance of each of those characters with the letter “x.” It doesn’t replace a substring.

Leave a Comment

Taking Advantage of Newer Date Functions in SQL Server

Andy Brownsword gets beyond SQL Server 2000:

Date handling in SQL Server tends to accumulate tried and trusted combinations of DATEPART()DATEADD(), and DATEDIFF() – with nested variations. The challenge with these isn’t raw performance, but more with conveying intent and readability.

So let’s look at some simpler patterns to try and avoid some of these and be clearer with what we’re trying to achieve.

Click through for some functions that have been around since 2012, and others that just became available in 2022.

Leave a Comment

The Value of TRY_PARSE()

Steve Jones answers a question:


Someone asked why I would use TRY_PARSE after I posted a question at SQL Server Central: Getting the Average. Isn’t is slower?

A fair question. This quick post looks at why.

I’d use TRY_CAST() or TRY_CONVERT() in this particular scenario. The main reason I’d use TRY_PARSE() would be if you need .NET-specific parsing functionality, such as parsing dates by a specific locale. The reason is that PARSE() and TRY_PARSE() are an order of magnitude slower than their CAST() and CONVERT() cousins.

That said, Steve’s example reminds me of a PolyBase demo I used to do, in which I took a CSV of North Carolina populations by county and read in the information. In that particular dataset, they would use the letter “A” to describe either “Not enough people to show an answer without potentially violating PII” or “We don’t know what the answer is.” So even though it was clearly a numeric attribute in “Population,” the output process overloaded the definition of that attribute and the only way you would know is to happen to see the three rows in ~1500 that happened to have an A in the column value.

Leave a Comment

Dealing with Catch-All Queries

Dualcore DBA handles an overly broad class of query:

We have a query that SELECTs from the Users table that takes multiple optional parameters and filters the output based on those.

Whilst fairly easy to read and write, queries written in this way often underperform.

This is a very generous understatement. Click through for two ways to improve the performance of such queries, as well as the pros and cons of each.

Leave a Comment

Implementing the Gauss Kronod Quadrature Formula in SQL Server

Sebastiao Pereira implements a formula:

Gauss-Kronrod quadrature is a numerical integration method that extends the Gaussian quadrature providing high accuracy and a built-in error estimation. It is based on the work of Carl Friedrich Gauss and Alexander Kronrod. The Kronrod method reuses all Gauss nodes adding extra points obtaining one integral estimate for Gauss and another for Kronrod and the differences gives the estimated error.

Click through to see how you can do this in T-SQL.

Leave a Comment

Simplifying Code via Computed Columns

Andy Brownsword moves an expression:

Computed columns allow us to bake logic into our schema. I find particular use for these when reviewing or optimising established solutions where you spot the quirky ways the data is being used.

Here I want to demonstrate 3 symptoms and show how different implementations of computed columns solve them.

Click through for the technique. It certainly won’t solve every performance problem relating to non-SARGable functions, but it does work pretty well on specific classes where you have limited control over the code.

Leave a Comment