Skip to main content

Clustered Foolishness

I had morning coffee with a well respected friend of mine recently. Aside from chatting about the usual wifery and family, we touched on the subject of clustered indices and SQL Server performance.

A common misconception in the software industry is that a clustered index will make your database queries faster. In fact, most cases will demonstrate the polar opposite of this assumption. The reason for this misconception is a misunderstanding of how the clustered index works in any database server.

A clustered index is a node clustering of records that share a common index value. When you decide on an index strategy for your data, you must consider the range of data to be indexed. Remember back to your data structures classes and what you were taught about hashtable optimizations.

A hashtable, which is another way of saying a database index, is just a table of N values that organizes a set of M records in quickly accessible lists that are of order L, where L is significantly less than M. If your index/hashtable is poorly performing, then you have a problem with your L and N, i.e. your N is approaching M and your L is approaching 1.

A clustered index is something special because it is the only index that dictates how data is PHYSICALLY stored on disk. While a simple index is an in-memory data structure, the clustered index is a physical clustering of the data records (order L from prior paragraph) written to storage. This is the killing joke of a clustered index because the worst case scenario of your index is to constantly change its range, which means you're constantly recreating your clusters. That, my friends, is why your database gets slower as it fills with records.

Your solution is to never use a clustered index unless you have a finite, pre-determined, range of index values. The clustered index is only best-performing when the key range is static, or rarely changing.

A common mistake is to set a record ID in your table to be your Primary Key, which by default is also clustered. Oops. That means your key space for that primary clustered key is always changing with every insert. Crap, right? I bet you've got a few of those in your database right now. You better run off and fix that right now.

You might wonder why this is such a big deal, right? At what point does the clustered index start to fail? Thousands of records, hundreds of thousands, millions? Those are good questions.

Every index in a database is ordered. This is a requirement so that searching the index space can be done in log(n) time. This is also the reason why the physical layout of a clustered index is so problematic. Each time the index space changes, the physical layout of the records must be recomputed and stored. A write operation to a hard disk is orders of magnitude slower than one in memory, and so the cost of rewriting the ENTIRE INDEX SPACE becomes prohibitive as the indexed table grows in size. Sound familiar? Even with fill factors set as high as 90%, you will feel the bite of rewriting the clustered index space if your index range changes rapidly.

I've found that the clustered index on a bad key range starts to fail around a hundred thousand records, but that depends on the size of your records and the speed of your hard drives. If you have high speed (AV-rated) SCSI drives, then you might be able to get away with more records. Once you hit a million records, though, you're sunk, no matter how fast the hard drive.

Your remedy is to always use non-clustered indices for your primary keys. The very nature of a primary key is that it must be unique, which is orthogonal to the idea of a clustered index. In SQL Server, the clustered nature of a key is a constraint, so you have to ALTER the table and DROP the constraint, and then re-create the primary key without clustering.

Then when you decide to add other indices to your tables, only do it on columns that are used in queries. Take advantage of multi-column indices because many times, your searches are multi-column filtered.

If you absolutely need to use a clustered index to make your row sorting faster, then do it on a static key space, or one that is almost never changing.

Popular posts from this blog

Number of Primes

Anderson's Theorem (a) The number of primes in [1,n] is no more than 2+floor(n/2). The probability of n being prime when n is not prime is 1/2 - see Dasgupta,Papadimitriou,Vazirani "Algorithms" page 26. Therefore, the E(pi(n)) is n/2. (b) There does not exist another set of adjacent primes other than {1,2,3} 5: 2 + floor(5/2) = 2 + 2 = 4:=> {1,2,3,5} : 4 <= 4 7: 2 + floor(7/2) = 2 + 3 = 5 => {1,2,3,5,7} : 5 <= 5 11: 2 + floor(11/2) = 2 + 5 = 7 => {1,2,3,5,7,11} 6 <= 7 26: 2 + floor(26/2) = 15 => {1,2,3,5,7,11,13,17,19,23} : 10 <= 15 Lagrange's Theorem is Inaccurate Lagrange's theorem about primes states that pi(x) is the number of primes <= x. The pi(x) is approximately x/ln(x). He postulated that the lim of pi(x)/(x/lnx) as x-> infinity was 1. This is incorrect. if the number of primes is bounded by n/2 then refactoring and reducing Lagrange's Theorem results in the lim of ln(x) as x approaches infinity. This is alwa...

How To Cancel ATT Uverse

I was a subscriber to the AT&T Uverse service for a little over 2 years. In that time, we had experienced good service for the first year, and then it sucked. After 12 months, or there in, the service degraded quickly, and would stop working all together at times. At first it would die for a short period of time, usually when we were not home. Then it would get progressively worst, until there was an entire week of no service. We had technicians at the house trying to fix the service, but it would repeat the behavior quite consistently. On January 15th we finally gave up and switched to a lesser service, COX TV and Internet. In the past we had cable service and it was always reliable, but not as good as the AT&T digital service. COX doesn't have nearly as many HD channels, but that's not enough. We needed internet to be reliable, and AT&T couldn't deliver that. Cancelling the AT&T service was a nightmare. Try to find anything about such things on their web s...

A Self Defeating Race False Narrative

2020 is the year of the pandemic. The SARS-Cov-2 (Covid19) virus has rampaged across the planet infecting 4,893,136 [1] people by May 20, 2020. At this time, of those 4.8M people, 323,256 people have perished from complications that arise from the infection. Arising out of this pandemic has been a narrative about non-white ethnic groups being disproportionately affected by the infection [6,7,8]. A narrative that conditions people to believe that they are perpetually victims only creates a "collective victimhood" [4,5] in that group. This "collective victimhood" costs its members millions in unrealized potential, sends them cowering from social interactions that would otherwise benefit them, and ultimately creates an environment that perpetuates itself. Let's try to dispel that false narrative and deal just with data. I pulled my data from the CDC [9] looking at mortality only. The mortality data from CDC contains per-state mortality rates on a per-infectio...