Press "Enter" to skip to content

Category: Performance Tuning

Entry Points and Graph Neighborhoods with DiskANN

Mala Mahadevan tries something out:

I was experimenting with vector search in SQL Server 2025 using approximately 3.8 million Hacker News articles that that I used for my talk on SQL Server-based vector search feature at EightKB. I generated two sets of embeddings from the same articles: one stored as FP32 (32-bit floating point) and the other as FP16 (16-bit floating point). Both sets contained the same articles and used DiskANN vector indexes.I used a query as below to find articles similar to a selected example.

What Mala found was that FP16 queries could sometimes take longer and require more reads than FP32 queries, which doesn’t make sense on its face. Click through to see two experiments she devised to come up with the answer.

Leave a Comment

When ApproximateDistinctCount is Slower than DistinctCount in DAX

Chris Webb explains the paradox:

As a follow-on from last week’s post about the new ApproximateDistinctCount function in DAX, I want to share something I found out from my recent testing for this function: ApproximateDistinctCount is sometimes slower than DistinctCount. This sounds counter-intuitive, right? After all ApproximateDistinctCount is a performance optimisation for the sometimes slow, expensive DistinctCount function. But it turns out that there are certain engine optimisations for DistinctCount that can’t be replicated for ApproximateDistinctCount which mean that for low-cardinality columns using DistinctCount can be faster.

Click through for an example.

Leave a Comment

A Statistical Error

Hugo Kornelis tells a story:

Anyway, the load process at this customer had multiple steps. Truncate and then fill staging tables with the current data from various source systems. Use the data in those staging tables to update the first of the data vault tables. And then use a join between the same staging table plus the just updated data vault table, with a filter on the current date, to update all other data vault tables.

With some of the tables having more than 500 million rows and over 50 columns, this process needed some time. But that was not a problem. The load finished before the offices reopened. Usually. But not always. Sometimes, it would run a few hours longer. And nobody knew why the load would take extra time at those seemingly random moments.

Read on for the full story. It’s a sobering reminder that each environment is different, and something that worked really well in one environment may fare poorly elsewhere.

Leave a Comment

Clustering in Fabric Data Warehouse

Louis Davidson does some exploring:

Clustering is one of the data terms that could not have been created by a database design person. Why? Because it has multiple meanings. In PostgreSQL it means the same thing as an instance in SQL Server. In server architecture it means connecting multiple servers together to form a “single” unit of some form to protect against failure. Then it means an index that determines the physical storage of a table in some manner. This usage of the word means the former.

The weirdest part of using a Fabric Data Warehouse when you first try to look at a query is the lack of indexes. So (currently as of writing this is late 2026), you only have this one tool to affect your performance. The tool allows you to order the data physically in your files so query processing can be reduced when searching the physical file.

Read on for an introduction of how it works, with the caveat that Louis is about two pages ahead of most people in the book.

Comments closed

Compiling Power BI Calculation Groups

Phil Seamark looks at an optimization:

Power BI now avoids compiling calculation items that a query has already filtered out. The time saved is before the first storage engine event. It does not make the scans themselves faster.

Will I benefit? If your query filters a calculation group down to a subset of its items, it may compile faster. A single filtered group can benefit, although often only by a little. The largest gains are in models where calculation groups reference one another, because the engine used to expand combinations the query never needed. If your query has no calculation groups, or uses every item in them, there is nothing to prune.

Click through to see what the hubbub is all about and if it might affect you.

Comments closed

Choosing COUNTROWS() over DISTINCTCOUNT() in DAX

Phil Seamark provides some guidance:

Counting transactions is one of the most common things a retail model is asked to do. How many transactions did we do in March. How many in New Zealand. How many involved a T-shirt.

The obvious measure is the one everybody writes:

Transactions = DISTINCTCOUNT ( FactTransaction[TransactionID] )


It is correct, and on a large fact table it is one of the most expensive things you can ask the storage engine to do.

Read on for a better alternative, and more importantly, when it’s a better alternative.

Comments closed

A Performance Monitoring Update

Erik Darling has a new video:

Erik Darling here with Darling Data, the one, the only, the monitoring tool mogul of SQL Server. Today I wanted to sort of update people on the state of the performance monitor project because there are some things that are useful to the general population that I feel like I should bring up.

So the current version of the performance monitor is 3.1. If it’s been a while since you’ve tried this thing out, I would suggest giving it another shot because there have been some really, really big improvements, not only in the collected data and sort of visualization and printification of things, but also in the UI, UX, the sort of experience that you get out of it.

Click through for the video and make sure you don’t get sucked into any organ harvesting rings. They may sound alluring at first, but they never work out the way you want them to.

Comments closed

PostgreSQL HOT Tables and TPC-C Workloads

Avinash Vallarapu tunes a PostgreSQL implementation of the TPC-C workload:

Vacuum is almost always presented as a pain point, a culprit, and an over exaggerated source of performance problems in PostgreSQL. The MVCC implementation in PostgreSQL is different from Oracle, SQL Server, MySQL or MariaDB, and that implementation introduces two requirements of its own, freezing transaction IDs, which is largely seamless, and clearing dead tuples through the various forms of vacuum. At the same time the PostgreSQL community is far ahead in minimizing the impact of vacuum. Each release has introduced enhancements substantial enough that most users never realize vacuum is something they could tune at all, and the list of vacuum specific improvements is long enough to deserve an article of its own. Among all of those optimizations, one of the most often missed is how to avoid the need for vacuuming in the first place. That is achievable most of the time, and it is not new.

Pavan Deolasee worked on the idea through 2006 and 2007 and authored the concept of the Heap Only Tuple, or HOT. Simon Riggs, Heikki Linnakangas, Tom Lane and many other PostgreSQL core team members and contributors have written a great deal of enhancement around it since. In this article we look at what PostgreSQL HOT updates actually are, how fillfactor decides whether they succeed, and how we identify which tables benefit. We then put it to the test with a HammerDB benchmark using the HammerDB TPROC-C workload against PostgreSQL 18.4, six 60-minute runs across three dataset sizes, and the improvement from correctly applied PostgreSQL HOT updates is substantial.

Read on for an overview of HOT tables and the results of this experiment.

Comments closed

Building Oracle’s Automatic Workload Repository in Postgres

Kellyn Gorman simulates some functionality:

Moving from Oracle to PostgreSQL means losing one of Oracle’s most-loved diagnostic tools: the Automatic Workload Repository (AWR). The good news? Most of AWR’s core capabilities – snapshot history, wait event sampling, Top SQL analysis, and buffer cache inspection – have direct, open-source equivalents in PostgreSQL.

This guide translates Oracle AWR concepts into practical PostgreSQL diagnostics using extensions like pg_profile, pg_wait_sampling, and pg_stat_statements – complete with runnable SQL you can apply to your own environment today.

Read on to see how.

Comments closed

Optimized Locking in SQL Server 2025

Louis Davidson tries out a new feature:

A feature I have been trying to find time to write about since it arrived is Optimized Locking, which first shipped in SQL Server 2025. This is a feature that changes the way SQL Server locks manages concurrency in a very interesting number of ways. Most of which, as I start writing this blog, I don’t understand. And I probably won’t when I finish.

What I can promise you is an example rich blog where I examine the impact of this feature.

Read on to see what Louis was able to learn.

Comments closed