Производительность JOIN: составной ключ по сравнению с первичным ключом BigInt - PullRequest
1 голос
/ 12 марта 2009

У нас есть таблица, которая будет, скажем, от 100 миллионов до миллиарда строк (Имя таблицы: Архив)

На эту таблицу будут ссылаться из другой таблицы, Пользователи.

У нас есть 2 варианта первичного ключа в таблице Archive:

вариант 1: dataID (bigint)

вариант 2: userID + datetime (4-байтовая версия).

Схема:

Пользователи - userID (int)

Архив - Идентификатор пользователя - дата и время

OR

Архив - dataID (большой int)

Какой из них будет быстрее?

Мы уклоняемся от использования варианта № 1, поскольку bigint имеет размер 8 байт и 100 миллионов строк, которые в сумме добавят объем памяти.

Обновление Хорошо, извините, я забыл упомянуть, userID и datetime должны быть независимо друг от друга, поэтому мы не добавили еще один столбец dataID в таблицу.

Ответы [ 4 ]

1 голос
/ 12 марта 2009

Обеспокоенность: Использование идентификатора пользователя / [small] datetime несет в себе высокий риск не быть уникальным.

Вот настоящая схема. Это то, о чем ты говоришь?

-- 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
)

Если бы это было мое решение, я бы определенно получил вариант 1. Диск дешев.

Если вы выберете вариант 2, вполне вероятно, что вам придется добавить какой-то другой столбец к вашему ПК, чтобы сделать его уникальным, тогда ваш дизайн начнет ухудшаться.

1 голос
/ 12 марта 2009

Некоторые мысли, но, вероятно, нет однозначного решения:

  • Если у вас есть миллиард строк, почему бы не использовать int, который идет от -2,1 миллиарда до +2,1 миллиарда?

  • Идентификатор пользователя, int, 4 байта + smalldatetime, 4 байта = 8 байтов, такой же, как bigint

  • Если вы думаете о userid + smalldatetime, то это, безусловно, полезно в любом случае. Если это так, добавление суррогатного столбца «archiveID» в любом случае увеличит пространство

  • Требуется ли фильтрация / сортировка по идентификатору пользователя + smalldatetime?

  • Удостоверьтесь, что ваша модель верна, позже позаботьтесь о СОЕДИНЕНИЯХ ...

0 голосов
/ 12 марта 2009

Я рекомендую вам установить симуляцию для проверки этого в вашей среде, но я предполагаю, что один bigint будет быстрее в целом; однако, когда вы запрашиваете таблицу, на что вы будете запрашивать?

Если бы я строил архив, я мог бы использовать поле идентификатора автоинкремента, а затем использовать схему разбиения для разбиения на основе DateTime и, возможно, идентификатора пользователя, но это зависело бы от обстоятельств.

0 голосов
/ 12 марта 2009

Что с вариантом 3: сделать dataID 4-байтовым int?

Кроме того, если я правильно понимаю, на таблицу архива будут ссылаться из таблицы пользователей, поэтому даже не имеет смысла иметь ID пользователя в таблице архива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...