Primary keys for an OLTP database

  • Jeff Moden - Friday, December 28, 2018 8:59 AM

    So, I wondered what the results would be on the 48 core, 384GB RAM, SSD fire breather at work... here are those results from the first run.  Subsequent runs did pan out roughly the same way...

    data:image/png;base64,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

    My i5-4310U 4 Logical Cores @ 2.00GHz system, 512GB SSD, Microsoft SQL Server 2016 (SP1-GDR) (KB4458842) - 13.0.4224.16 (X64) is optimized to the extreem for running the SQL Server Service, quite amusing to see it outperform the 48 core, 384GB RAM, SSD fire breather at your work, maybe I should drop around for some tuning!
    😎


    T_TXT              DURATION
    ------------------ -----------
    IDENTITY 3             1900222
    IDENTITY 1             1900764
    IDENTITY 2             1921514
    NEWSEQUENTIALID 2      2401202
    NEWSEQUENTIALID 1      2404004
    NEWSEQUENTIALID 3      2472017
    NEWID 2                3437846
    NEWID 3                3561873
    NEWID 1                3589680



  • xsevensinzx - Saturday, December 29, 2018 7:11 AM

    Jeff Moden - Friday, December 28, 2018 9:24 AM

    xsevensinzx - Friday, December 28, 2018 8:08 AM

    Jeff Moden - Friday, December 28, 2018 7:54 AM

    xsevensinzx - Friday, December 28, 2018 7:47 AM

    I've said it in other threads, did not like the performance of a clustered GUID (non-unique) on billions of records in a single fact table within a SMP system. I had to cleanse the keys for sequentials. But, in the MPP columnstore world, I absolutely love GUID because the randomness is great for clustering the data pretty evenly across N databases without having any single database with more or less records than the others.

    Now there's an interesting aspect.  Thanks.

    Just for further clarification.

    You have to hash data using a key with each table. This is like adding a clustered index to define how the data is stored on disk. Being there is 60 databases with N disks per database, you want to ensure the key you select has a even distribution of that data across those databases. Thus, if you have 500 million records with random keys and 1 billion records with 0 as their key, then 1 of those 60 databases will have 1 billion records stuck in it where the other 59 databases would have evenly distributed the remaining random keys the best they could, which is likely about 8 million per database.

    If you write a query to read some of those 0 keys, you would have just 1 computer working for you versus if you wrote one for the other keys, you would have 59 databases and their computers working for you. Thus, using the GUID in place of these keys, including the 0 keys, can help evenly distribute the data evenly across all computers/databases/etc. Hopefully about 25 million per database in this example now that you have used the GUID key to help evenly distribute the data.

    Using the sequential here may be bad because it ticks the ranges forward in a linear fashion causing the distribution to always shift forward with the data as it comes into the system. The same is true for date/time.

    Good stuff right there and it's confirmation of what I told folks when they wanted to invest in an MPP appliance at one of the companies that I work do work for.  The hype (I know you already know this and have confirmed that knowledge with what you wrote above) was that MPP would make things run 30X faster.  Everyone but me was ready to loosen up their purse strings even though I didn't have much knowledge of MPP appliances but knew enough to know better.  And so I challenged the salesman on the spot... "Tell them what the necessary modifications are to the underlying data structure and code is to achieve that 30X improvement.  Then explain why the expenditure of that amount and cost of development and testing, not to mention the cost of the appliance itself, is better than spending the time to tweak the code to make it run 60 to 1000 times faster" and cited several major examples where we had done so.

    Understand, that they don't have the billions of rows in tables that you do.  They only recently (in the last year) had a database go over the 2TB mark and I just got rid of half of that data for them (with their concurrence, of course) because it was never accessed and was duplicated in other places.

    Thanks again for the awesome information.  I'll probably never have the opportunity to work on such a system as what you do.  To be honest, I'm not sure I'd want to but it would be interesting.

    Yes, you will need to alter the model to make it work in the MPP world. The prime example is the fact your hashing key can only accept a single key in most MPP systems. You cannot for example hash on more than one key. This causes you to replicate data on different hashing keys for different computational processes. Dimension tables that are below 60 unique keys or under 2 GB in size, will need to be treated differently than larger dimensional tables in how they are distributed across those 60 databases. For example, instead of hashing on a key, you have to choose replicate, which will not distribute the data across 60 databases, but replicate the entire dataset per database. When you modify that table, you will need to constantly rebuild it with SELECT TOP 1 * FROM DimTable. Dimensional tables are commonly modified when new dimensional values come into the system. Thus you have to fact that in.

    I won't even go into the design decisions needed for concurrency slots as most MPP does not allow every process to run at the same time. Queuing systems with concurrency values are needed in meaning, not only do you have to schedule your ETL, but also put them into priority order and how much currency they can use when running in batches.

    Anyways, I moved to MPP not just for the big data stuff, but also for the fact a good portion of my data is alphanumeric like GUID's. This is surely a good example of where GUID's perform the best and can be used with ease.

    Understood but what a fascinating sidebar you've provided!  Thanks for taking the time to explain a bit about MPP, especially how it all relates to the use of GUIDs.  I've added this discussion to my briefcase.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Eirikur Eiriksson - Saturday, December 29, 2018 8:08 AM

    My i5-4310U 4 Logical Cores @ 2.00GHz system, 512GB SSD, Microsoft SQL Server 2016 (SP1-GDR) (KB4458842) - 13.0.4224.16 (X64) is optimized to the extreem for running the SQL Server Service, quite amusing to see it outperform the 48 core, 384GB RAM, SSD fire breather at your work, maybe I should drop around for some tuning!

    Ya know, it's funny that you've mentioned that.  I've noticed for quite a while that my laptop (an older Vaio of a similar config as yours but with no SSDs and only 4GB dedicated to SQL Server) frequently outstrips the fire-breather at work in certain areas.  In other cases, the one at work blows my laptop away.  I've been trying to figure out why but, so far, haven't found out why.  If we weren't using SSDs at work, I'd be temped to blame it on the ol' sector offset problem except that some memory-only stuff is also slower.

    I'd love to have someone else take a look sometime.  I can't do such a thing remotely, though.  Totally "against the rules" I have to follow.  I might be able to convince folks to make an exception, though, especially if it's a "watched" session.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Jeff Moden - Sunday, December 30, 2018 9:45 AM

    Eirikur Eiriksson - Saturday, December 29, 2018 8:08 AM

    My i5-4310U 4 Logical Cores @ 2.00GHz system, 512GB SSD, Microsoft SQL Server 2016 (SP1-GDR) (KB4458842) - 13.0.4224.16 (X64) is optimized to the extreem for running the SQL Server Service, quite amusing to see it outperform the 48 core, 384GB RAM, SSD fire breather at your work, maybe I should drop around for some tuning!

    Ya know, it's funny that you've mentioned that.  I've noticed for quite a while that my laptop (an older Vaio of a similar config as yours but with no SSDs and only 4GB dedicated to SQL Server) frequently outstrips the fire-breather at work in certain areas.  In other cases, the one at work blows my laptop away.  I've been trying to figure out why but, so far, haven't found out why.  If we weren't using SSDs at work, I'd be temped to blame it on the ol' sector offset problem except that some memory-only stuff is also slower.

    I'd love to have someone else take a look sometime.  I can't do such a thing remotely, though.  Totally "against the rules" I have to follow.  I might be able to convince folks to make an exception, though, especially if it's a "watched" session.

    Ping me a PM or an email with the whole specs of the fire breather, very interested in knowing what causes the difference.
    😎 

    I'm prepping my own fire breather, 64 cores, 512 Gb memory, eight storage controllers,  8 Tb of SSDs, latest generation which exceed 100000 iops/sec each, four per channel, slightly hesitant as it cost me more to run it than to heat the house.

  • Eirikur Eiriksson - Sunday, December 30, 2018 10:53 AM

    Jeff Moden - Sunday, December 30, 2018 9:45 AM

    Eirikur Eiriksson - Saturday, December 29, 2018 8:08 AM

    My i5-4310U 4 Logical Cores @ 2.00GHz system, 512GB SSD, Microsoft SQL Server 2016 (SP1-GDR) (KB4458842) - 13.0.4224.16 (X64) is optimized to the extreem for running the SQL Server Service, quite amusing to see it outperform the 48 core, 384GB RAM, SSD fire breather at your work, maybe I should drop around for some tuning!

    Ya know, it's funny that you've mentioned that.  I've noticed for quite a while that my laptop (an older Vaio of a similar config as yours but with no SSDs and only 4GB dedicated to SQL Server) frequently outstrips the fire-breather at work in certain areas.  In other cases, the one at work blows my laptop away.  I've been trying to figure out why but, so far, haven't found out why.  If we weren't using SSDs at work, I'd be temped to blame it on the ol' sector offset problem except that some memory-only stuff is also slower.

    I'd love to have someone else take a look sometime.  I can't do such a thing remotely, though.  Totally "against the rules" I have to follow.  I might be able to convince folks to make an exception, though, especially if it's a "watched" session.

    Ping me a PM or an email with the whole specs of the fire breather, very interested in knowing what causes the difference.
    😎 

    I'm prepping my own fire breather, 64 cores, 512 Gb memory, eight storage controllers,  8 Tb of SSDs, latest generation which exceed 100000 iops/sec each, four per channel, slightly hesitant as it cost me more to run it than to heat the house.

    Heh... so stop heating the house. 😀  The system will do that for you.  By a 20" (~51 cm) box fan to push some air around.

    Will do on the specs.  Anything in particular that you'd like me to include so that I don't miss it?

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Although this topic came quite late to my attention it is more actual than ever. I see lots of people favorite sequential INT/BIGINT as PK but - as Jeff has mentioned - it does not scale. I would say it sucks 🙂

    The topic of the article is about OLTP! OLTP in general do not work with big data sets like DWH do. So the problem of index fragmentation is not a big issue here!

    The demo from Erikur (where Identity wins!) has nothing to do with a heavy load scenario from real world OLTP systems. So if just one process is hitting a table you won't run into "last page contention".

    My tests which I show whenever I do a session about DML optimization shows that a random value (whether GUID or others) will win always.

    A big problem can be a big table with billions of rows because of the traversal access to the pages where the new record has to be stored.

    In this case I favorite HEAPS over C.I. with a NONCLUSTERED PK. Most of my tests and workload optimizations at customer sites did win the race with heaps and an intelligent underlying file layout (e.g. I use to implement databases with high DML operational workload on multiple files in a filegroup!)

    My personal advice here is:

    • You can use an ascending key in business environment with <= 1000 transactions / min
    • If your system should scale you should think about a redesign of the PK data type and value AND usage of C.I vs. HEAP

    Microsoft Certified Master: SQL Server 2008
    MVP - Data Platform (2013 - ...)
    my blog: http://www.sqlmaster.de (german only!)

  • What I haven't seen in this conversation is any control for uniqueness. Certainly one can argue that a monotonically increasing record (not row) counter is unique. It does, however, allow otherwise entirely duplicate rows to be entered but they are, of course, unique because they have a new incremental value. How will you control uniqueness assuming that you find it incorrect to have a line item billed to a customer 100 times when they only ordered 1...but the database has not controlled for truly unique content?

    I can already hear the shouts that such business rules belong in the application. Then you better make sure your application covers all the things support personnel and/or DBAs might need to accomplish because SSMS will not be constrained by the beautiful micro service business rule implementation behind your mobile application. And believe me, someone WILL need to go into your database to fix things.

    ------------
    Buy the ticket, take the ride. -- Hunter S. Thompson

  • Bryant McClellan wrote:

    What I haven't seen in this conversation is any control for uniqueness.

    ... How will you control uniqueness assuming that you find it incorrect to have a line item billed to a customer 100 times when they only ordered 1...but the database has not controlled for truly unique content?

    ...

    Generally speaking, the primary key is the key intended for reference in foreign key relationships with other tables. But there can still be another unique index on the natural key. For example, we wouldn't expect the same point of sale (POS) terminal to process two transactions at the exact same moment. In the real world, it could potentially happen (maybe) if two POS terminals were setup wrong with the same PosID. But here we have a sequentially incremented primary key and then an index enforcing uniqueness on three columns that represent logical place + time.

    PRIMARY KEY:   PosTransactionId (INT)

    UNIQUE INDEX:   Store (VARCHAR(5)), PosID (SMALLINT), TransactionTime (DATETIME)

     

    "Do not seek to follow in the footsteps of the wise. Instead, seek what they sought." - Matsuo Basho

  • Another point to consider; if the primary key is also a foreign key in other tables, there could be a significant impact in using one that takes up 16 bytes instead of 4 (or 8).

    On the subject of natural vs artificial keys; I tend to use an INT or BIGINT surrogate in addition to any available natural key. The surrogate would be the one repeated in other tables as a foreign key, but the customer would quote the more memorable natural key. Which of them gets used as the primary key in the main table would depend on the types of query anticipated.

  • And fairly straightforward to accomplish. All I was after is that it is a common failing that usually manifests itself at the worst possible time. I was also reminded of this from some of Jeff Moden's earlier comments regarding the definition of natural keys.

    ------------
    Buy the ticket, take the ride. -- Hunter S. Thompson

Viewing 10 posts - 46 through 54 (of 54 total)

You must be logged in to reply to this topic. Login to reply