THE SQL Server Blog Spot on the Web
Welcome to SQLblog.com - The SQL Server blog spot on the web Sign in | Join | Help
in Search

Michael Zilberstein

Partitioning by GUID

Recently I had to use GUID (Global Unique Identifier) as primary key in order to ensure cross-server uniqueness. In many cases surrogate key (some sort of concatenation between server id and intra-server identity) would give a better performance but in my case due to application requirements surrogate key wasn't an option.

Next step is partitioning by GUID column. Say, you want 3 partitions. Ho do you build partition function? Sure, you can perform a calculation and find the exact 2 values that will divide all the GUID range to 3 equal parts. I needed at least 20 partitions, so I used an approximation. If you write down long hexadecimal number, you'll receive something like A09F76... I decided that partitioning by first 2 tabs is enough. Example for decimal: let's divide values from 1 to 10000 to 3 partitions - what would be the ranges? The exact answer is: 1 - 3333, 3334 - 6666, 6667-10000. Using approximation by 2 first digits will give the following ranges: 1 - 3300, 3301 - 6600, 6601 - 10000. 2 orders of magnitude (first 2 digits) are good enough approximation. In hexadecimal first 2 digits (00 - FF) represent 0-255 in decimal. I'm not accustomed to hexadecimal calculations, so first I divide decimal range to 3 parts: 1 - 85, 86 - 170, 171 - 255. Next step is converting it to hexadecimal: 01 - 55, 56 - AA, AB - FF.

OK, done with values, how do I translate them into GUID? For example, 01 in hexadecimal - what is the GUID representation of it (taking into account that those should be first 2 digits - not the last ones). Took me awhile to understand. First I tried "01000000-0000-0000-0000-000000000000" - surprisingly all the rows (more then a million) came to the first partition. OK, another try: "00000001-0000-0000-0000-000000000000". Still the same. The catch is that GUID should be read in a byte groups order from right to left while inside every byte group reading order is from left to right. And every 2 tabs are 1 byte. So the right representation for 01 as first 2 digits in GUID is: "00000000-0000-0000-0000-010000000000".

To finish with, partition function that partitions GUID to 20 range groups:

CREATE PARTITION FUNCTION [pf_GUIDRangePartition](uniqueidentifier) AS RANGE RIGHT 
FOR VALUES 
(
  
N'00000000-0000-0000-0000-0D0000000000',
  
N'00000000-0000-0000-0000-1A0000000000',
  
N'00000000-0000-0000-0000-270000000000',
  
N'00000000-0000-0000-0000-340000000000',
  
N'00000000-0000-0000-0000-410000000000',
  
N'00000000-0000-0000-0000-4E0000000000',
  
N'00000000-0000-0000-0000-5B0000000000',
  
N'00000000-0000-0000-0000-680000000000',
  
N'00000000-0000-0000-0000-750000000000',
  
N'00000000-0000-0000-0000-820000000000',
  
N'00000000-0000-0000-0000-8F0000000000',
  
N'00000000-0000-0000-0000-9C0000000000',
  
N'00000000-0000-0000-0000-A90000000000',
  
N'00000000-0000-0000-0000-B60000000000',
  
N'00000000-0000-0000-0000-C30000000000',
  
N'00000000-0000-0000-0000-D00000000000',
  
N'00000000-0000-0000-0000-DD0000000000',
  
N'00000000-0000-0000-0000-EA0000000000',
  
N'00000000-0000-0000-0000-F70000000000'
) ;
Published Wednesday, June 11, 2008 4:40 AM by Michael Zilberstein
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
(optional)
(required) 
Submit
Powered by Community Server (Commercial Edition), by Telligent Systems
  Privacy Statement