2009-03-12 4 views
1

Nous avons une table qui va être dire 100 millions à un milliard de lignes (nom de la table: Archives)REJOIGNEZ Performance: clé composite par rapport BigInt clé primaire

Ce tableau sera référencé d'une autre table, les utilisateurs.

Nous avons 2 options pour la clé primaire sur la table Archive:

option 1: Dataid (bigint)

Option 2: userId + datetime (version 4 octets).

Schéma:

utilisateurs - ID utilisateur (int)

Archive - userID - datetime

OU

Archive - Dataid (grand int)

qui on serait plus rapide?

Nous hésitons à utiliser l'option 1 parce que bigint fait 8 octets et avec 100 millions de lignes qui s'ajoutent à l'allocation de stockage.

Mise à jour Ok désolé, j'oublié de mentionner, et datetime doivent userID être peu importe, ce qui était la raison de ne pas ajouter une autre colonne, Dataid, à la table.

+0

correction mineure: la phrase devrait être "ajouter à beaucoup de stockage". Allot a une signification complètement différente. – thursdaysgeek

Répondre

1

Quelques réflexions, mais il n'y a probablement pas une solution claire:

  • Si vous avez un milliard de lignes, pourquoi ne pas utiliser int qui va -2100-2100 million?

  • Userid, int, 4 octets + smalldatetime, 4 octets = 8 octets, même que bigint

  • Si vous envisagez de userid + smalldatetime alors sûrement ce qui est utile de toute façon. Si oui, l'ajout d'une colonne de substitution "archiveID" augmentera quand même l'espace

  • Avez-vous besoin de filtrage/tri par userid + smalldatetime?

  • Assurez-vous que votre modèle est correct, l'inquiétude au sujet JOIN plus tard ...

+0

Comme une alternative à la première puce, que diriez-vous d'un int non signé, qui va de 0 à 4,2 milliards? – Powerlord

+0

SQL Server n'a pas d'entier non signé :-) – gbn

0

Quoi avec l'option 3: Faire un Dataid 4 octets int?

Aussi, si je comprends bien, la table d'archivage sera référencée à partir de la table des utilisateurs, donc cela n'aurait même pas beaucoup de sens d'avoir l'ID utilisateur dans la table d'archivage.

0

Je vous recommande de configurer une simulation pour valider ceci dans votre environnement, mais je pense que le single bigint serait plus rapide en général; Cependant, lorsque vous interrogez la table sur quoi allez-vous interroger?Si je construisais une arhive, je pourrais avoir un champ d'identification auto-incrémenté, puis utiliser un schéma de partioning basé sur DateTime et peut-être userid mais cela dépendrait de la circonstance.

1

Préoccupation: L'utilisation de UserID/[small] datetime comporte un risque élevé de ne pas être unique.

Voici un vrai schéma. Est-ce ce dont vous parlez?

-- Users (regardless of Archive choice) 
CREATE TABLE dbo.Users (
    userID  int   NOT NULL IDENTITY, 
    <other columns> 
    CONSTRAINT <name> PRIMARY KEY CLUSTERED (userID) 
) 

-- Archive option 1 
CREATE TABLE dbo.Archive (
    dataID  bigint  NOT NULL IDENTITY, 
    userID  int   NOT NULL, 
    [datetime] smalldatetime NOT NULL, 
    <other columns> 
    CONSTRAINT <name> PRIMARY KEY CLUSTERED (dataID) 
) 

-- Archive option 2 
CREATE TABLE dbo.Archive (
    userID  int   NOT NULL, 
    [datetime] smalldatetime NOT NULL, 
    <other columns> 
    CONSTRAINT <name> PRIMARY KEY CLUSTERED (userID, [datetime] DESC) 
) 
CREATE NONCLUSTERED INDEX <name> ON dbo.Archive (
    userID, 
    [datetime] DESC 
) 

Si c'était ma décision, je l'aurais définitivement avec l'option 1. Le disque est bon marché.

Si vous utilisez l'option 2, il est probable que vous deviez ajouter une autre colonne à votre PK pour la rendre unique, puis votre conception commence à se dégrader.

+1

De plus, je n'utiliserais jamais de datetime dans un PK sauf s'il y avait un trigger qui ne pourrait jamais être mis à jour après l'insertion initiale. C'est juste un accident qui attend de se produire. – HLGEM

+0

grand point sur l'unicité Rob! – bigint

Questions connexes