Press "Enter" to skip to content

Category: Data Types

Making TOAST Work Better in Postgres

Shaun Thomas shares a story:

The performance of this table initially confused and enraged me—until I remembered about TOAST. Postgres likes to innocuously dub this backronym “The Oversized-Attribute Storage Technique” but DBAs in the field maintain a love/hate relationship with the system. Whether that’s justified is a different question.

On the surface, it’s a way to store huge blocks of data elsewhere to keep tuples small and avoid exceeding the relatively petite 8KB data page size. Postgres creates a shadow table for the bulky content, splits it up into chunks, and stores a pointer in the original row. It’s an elegant solution to a pressing issue, but there are deep performance implications.

So let’s dig into precisely why DBAs secretly dread large text-based columns, shall we?

Read on for the story and several tips to make a Postgres table with a blob of data faster.

Leave a Comment

Comparing JSONB to hstore in Postgres

Hubert Lubaczewski re-creates an issue:

Some time ago I read this blogpost.

They wrote about logging changes to table using a trigger, but one thing that caught my attention was:

Storing only the changed columns made the log five times smaller and the trigger slower.

Figured I can try it myself…

Unfortunately they didn’t provide schema of table, nor test updates. So, let’s make test case:

Click through for the demo, and how a change from JSONB to hstore for changed data improved performance a fair bit.

Leave a Comment

The Pain of Time Zones

Erik Darling makes an admission:

Erik Darling here with Darling Data, and in this video, we’re going to talk about mostly AT TIME ZONE performance, but also some other interesting stuff about AT TIME ZONE. I’m going to be real honest with you, I hate timezone stuff. I hate all of it. I’ve never taken naturally to it. It’s all too weird, and managing it is just such a nightmare. 

I agree with Erik’s point about storing everything in UTC. Click through to learn how you can slow things down considerably using AT TIME ZONE in certain ways.

Comments closed

Identity Column Reseeding and Clashes

Dualcore DBA violates Betteridge’s Law of Headlines:

I recently had cause to reseed an identity column on a table in SQL Server, which got me wondering “If we reseed an identity column to a value lower than the existing identity values in the column, could it cause a clash?” Because why wouldn’t you wonder if you can cause something to break, whilst performing a fairly simple task!?

Let’s find out what happens…

Click through for the demonstration.

Comments closed

Datatypes and Constraints in Microsoft Fabric Data Warehouses

Louis Davidson starts digging in:

There are three major “engines” in Fabric that I have seen that use T-SQL. There is the SQL Azure Fabric engine, the Lakehouse, and the Data Warehouse. Having this capability to manipulate data is wonderful, but there are some things you need to understand before you start writing code (unless you want to learn them the hard way like I have. I also will not profess to have found all of these differences. Changing my mindset when using these engines was the subject of this editorial

Read on for some inconsistency.

Comments closed

Identity Columns in Fabric Runtime 2.0

Jon Lunn is happy:

Fabric Runtime 2.0 is in public preview, and there is one small change for this that makes my life as a data engineer a little bit easier. Identity columns. I miss the good old T-SQL Identity column “Id INT IDENTITY(1,1)”, now we have something like it in Spark/Delta.

So with the the old spark/delta table runtime, you couldn’t have an default, automatically increasing column. But now we have these updates.

Click through to see how it works.

Comments closed

Explaining PostgreSQL Large Record Storage with TOAST

Radim Marek looks off-page:

In earlier posts in this series we established that every heap tuple lives inside a strict 8KB page. Everything else is built on top of that hard limit: MVCC, HOT updates, and indexes that point at (page, line_pointer). And yet this still works:

CREATE TABLE docs (id int PRIMARY KEY, body jsonb);
INSERT INTO docs VALUES (1, (SELECT jsonb_agg(g) FROM generate_series(1, 100000) g));

That body value is somewhere north of half a megabyte. The heap page is still 8KB. Both statements are true at the same time, and the mechanism that makes them coexist is TOAST: The Oversized-Attribute Storage Technique.

Read on to see how TOAST works, when it kicks in, and some of the consequences of this solution.

Comments closed

Parameter Types in DAX User-Defined Functions

Marco Russo and Alberto Ferrari talk about type systems:

In a previous article, Introducing user-defined functions in DAX, we described the syntax for creating user-defined functions, including the two passing modes (VAL and EXPR) and the fundamental parameter types SCALAR and TABLE. In this article, we build on that foundation and focus on the complete type system, with particular attention to the reference types introduced in March 2026 that provide better documentation, stronger validation, and improved IntelliSense support.

Before diving into the new types, let us briefly recap the full picture of parameter types and passing modes available in DAX user-defined functions.

Click through for a classic deep dive from Marco and Alberto.

Comments closed

Don’t Use FLOAT for Currency Data

Vlad Drumea has a public service announcement:

In this post I provide some examples as to why FLOAT isn’t the best option for storing exact financial data in SQL Server.

During the last couple of years I’ve seen quite a few cases of FLOAT being used to store financial data in SQL Server.
This isn’t ideal due to how the FLOAT data type behaves in SQL Server, and the official documentation makes a clear note of that.

I’m crotchety enough about this to say that you shouldn’t use any sort of decimal data type (DECIMAL, MONEY, etc.) when dealing with currency data in important financial contexts, either. I reach for BIGINT and divide by 100 (or 10,000 if you keep to four spots after the decimal) for the presentation layer.

For cases in which my data isn’t the source system of record for financial transactions, DECIMAL is fine. I don’t generally like MONEY as a data type in any circumstance, to be honest.

Comments closed

A Gotcha with pg_column_size()

Laetitia Avrot wants to know how large a column is:

Thanks to my colleague Ozair, who sent me a JIRA ticket saying “I need to drop that huge column, what are the consequences?” My first question was: how huge? That’s when the rabbit hole opened.

It looks simple. It is simple. Just use the administrative function pg_column_size(). Until you have toasted attributes. Then it gets interesting.

Read on for a demonstration.

Comments closed