Press "Enter" to skip to content

Category: Query Tuning

Bad Query Pattern: Wildcards on Both Ends

Chad Callihan covers this month’s T-SQL Tuesday topic:

A lot of SQL queries or code can still “work,” but that doesn’t mean it’s good, especially with so much vibe coding and the like going on these days. When I think of signs I’ve noticed when seeing a query for the first time, one thing that will get my attention (besides seeing NOLOCK throughout) is when a string is being searched for surrounded by percent signs.

I’ve had instances of working with someone that was looking for certain error logs. We may know the log record starts with “Error 123” and could search a field for “Error 123%” in our query.

Click through for the consequences of a search on “Error 123%” versus “%Error 123%”. Sometimes it’s simply necessary to do the full search, but if you find yourself doing that frequently, it’s a sign that you could design the table better.

Leave a Comment

Subqueries in the SELECT Clause

Louis Davidson tries out a few query forms:

The post states that a query such as:

SELECT soh.SalesOrderID,(SELECT  C.AccountNumberFROM    Sales.Customer AS CWHERE   C.CustomerID = SOH.CustomerID)AS CustomerAccountNumberFROM   Sales.SalesOrderHeader SOH;

will, by definition, execute that subquery on the Customer object one time per row in the SalesOrderHeader table.

But is this true?

Click through as Louis tests a few variants of this using SQL Server.

Leave a Comment

Ways to Find a Query Plan

Deborah Melkin has a list:

I’m very excited for this because I’ve wanted to put something together about this topic for a long time.

What inspired me is that I’ve really come to appreciate that there’s different pieces of information collected with the execution plan itself depending on where I get the plan from. Understanding what’s collected, where, and why can help make a difference when trying to troubleshoot and performance tune.

I get most of my query plans from a shady vendor with an unmarked van in a Walmart parking lot.

Leave a Comment

Two Pain Points in SQL Server Code

Steve Jones digs up a pair:

There are two things that immediately stand out to me when I see a query and create concern.

  1. cross joins
  2. functions in the where/on clause

While there are other things I might see, these two stand out and usually I can guess there will be issues.

Steve specifically calls out ANSI-89 style joins, which are awful. Before continuing, I agree with Steve’s points, but I figure I’d do a “yes, and” for this one.

When it comes to cross joins, there are specific circumstances in which I’ve written cross joins to great effect. The one that comes to mind most readily is when I need to create the raw data that will let you generate a matrix in a reporting tool.

Let’s say you want to know, for each sales territory and month, the number of new customers that month, the prior month, and the next month. The LAG() and LEAD() functions only work on rows, not intervals. Therefore, LAG() on the July row will show you the row prior to July. That might be June or it might be March, depending on how much data you have.

The solution, then, is to get the full set of months you care about from, say, a calendar table. Then, get the full set of sales territories. Cross join those two and you’ll have the entire range of relevant data. You can then left outer join to the actual data and fill in the gaps.

I have an example of this as a demo script on my Analyzing Business Data with T-SQL talk.

Leave a Comment

Starting Points for Query Tuning

Deborah Melkin shares some tips:

This one is really timely for me as I just started a new job. Performance tuning was part of the interview process so I’m really excited to dive back into doing more of that day-to-day. In fact, I just got added to the email reports with the top SQL results for the worst performers. Here’s some of what I’ll start looking at in that list and why:

Click through for Deborah’s red flag list. Of note, a red flag is not necessarily a bad thing. But it does merit further inspection and comment. For example, there may be specific instances in which join hints are necessary—you know you’re joining from a very small filtered subset to grab a tiny percentage of a bigger table (and you have an appropriate index on said bigger table), and so you slap on a LOOP join hint because the optimizer keeps trying to sort and merge join. But it’s worth explaining why and figuring out if there’s a better way, especially considering the consequences of slapping on that join hint.

Leave a Comment

The Pain of Functions Wrapping Columns in a WHERE Clause

Rebecca Lewis answers a question:

This post is part of T-SQL Tuesday #200, hosted this month by Brent Ozar. The prompt: “When I’m looking at a query, I bet it’s bad if I see ____.”

Easy. I didn’t even have to think about it. When I open a stored procedure and see a function wrapped around a column in the WHERE clause, I groan. Out loud. Because more often than not, it means the predicate is non-SARGable, and non-SARGable means your indexes just became very expensive shelf decorations.

That is a pretty good answer, yes. Almost nothing good comes from wrapping columns with functions in the WHERE clause or as part of a join criterion.

Leave a Comment

Controlling Memory Grants in SQL Server

Erik Darling has a new video:

So we’ve got this query here that I have pre-run because it takes a little bit to run. And I don’t want to stand here in the hot, light heat while I wait for all this. This query will ask for quite a big memory grant, both because it is written in a way with this derived join, which will force us to run this query and produce a result.

And two, because we are selecting all of the columns from the comments table, one of them being a column called text, which is in InvarCar 700. So just to sort of get ahead of things a little bit, this query asks for an 11 gig memory grant. If you want to fix a big memory grant, you have three basic things you can do for any given query.

Click through to learn what you can do.

Leave a Comment

Optimizing Polymorphic Associations in Postgres

Andrei Lepikhov continues a thread:

Recently, I looked into how common polymorphic associations actually are in relational databases — a performance-hostile pattern built around a discriminated foreign key that ORMs (Rails, Django, Hibernate), CRM platforms (Salesforce), and 1C generate automatically. The front page of a typical online store, or the activity feed of a CRM, is built by exactly this kind of query: a base table is LEFT JOIN-ed to every possible subtype through a (type, id) pair of columns.

That earlier article answered the question ‘how widespread is this pattern?’ After all, if you’re going to improve something, it helps to know how useful the improvement will be, right? Here, I want to give a sense of how this pattern leads to performance regressions and point out directions in the PostgreSQL optimiser that could make the situation easier.

Much of this is speculative in nature but the three proposed solution ideas are all interesting.

Comments closed

Working with Indexed Views

Erik Darling talks indexed views:

Anyway. T-SQL Server Management Studio. When most people think about index views, they rightfully think about all the stuff they can’t do with them.

And I sympathize with that because, man, so many times they’ve been like, oh, if only you could do this, if only you could do that, it sure would be nice. And I realize that all the air has gone out of the room as far as making index views more powerful because everyone’s like, well, you could just use batch mode.

Click through for some tips around update operations when dealing with indexed views, as well as a side rant about merge joins.

Comments closed