У меня есть таблица с первичным ключом (primkey), состоящая из (USER_NAME VARCHAR (50), AGE INT, DATE DATETIME) .Затем он индексирует кучу данных для пользователя в этот конкретный день.В общем, я бы запросил все данные для USER_NAME .
Исправьте меня, если я ошибаюсь - кластеризация здесь работает хорошо, поскольку сначала она будет кластеризована на основе USER_NAME поэтому выложу все данные для USER_NAME = JOHN_SMITH физически близко друг к другу.Затем он будет кластеризован на основе AGE и т. Д. Поскольку я запрашиваю все данные для конкретного пользователя, это должно означать, что IO оптимизирован, то есть я читаю наименьшее количество страниц и запрос, который запрашивает большой объем данных.и поэтому IO-ограничение является самым быстрым.
В настоящее время я планирую заменить (USER_NAME, AGE) на uid, который при последовательном увеличении числа является случайным отображением между (USER_NAME, AGE) и идентификатор пользователя.Это, конечно, также изменит значение первичного ключа на (UID INT, DATE DATETIME) Поскольку uid - это просто число, например (JOHN_SMITH, 24) может быть 123124 и (JOHN_SMITH, 25) может оказаться 352431, насколько я вижу, кластеризация становится бессмысленной.Я имею в виду, что хотя (JOHN_SMITH, 24) и (JOHN_SMITH, 25) в старом primkey явно являются данными для одного и того же пользователя в течение 2 последовательных лет, и БД будет кластеризоватьданные близко друг к другу на диске, номера 123124 и 352431 не содержат никакой информации о ссылочных данных.То есть старый primkey имел структуру, новый не имеет структуры и неявной информации о ссылочных данных.
Одним из решений является внедрение какой-либо схемы адресации в UID (например, стиль IPv4, нонамного проще) - каждый USER_NAME получает зарезервированное пространство из 150 UID, то есть если JOHN_SMITH получает UID 0, JOHN_SM Y TH получит UID не менее 150 и 0-149 зарезервировано для (USER_NAME = JOHN_SMITH, AGE =?) комбинации.
Я физически не хочу идти по схеме адресации.Любые мысли по этому поводу (в том числе, если моя теория верна) будут оценены.
- Я ограничиваю производительность в SELECT, меня не волнует INSERT и DELETE.
- Таблица Users очень велика (десятки ГБ).
РЕДАКТИРОВАТЬ: Пример запроса SELECT (значения, скорее всего, будут намного длиннее списка, а не только 2 элемента.
DECLARE @testtable TABLE
(
uid INT,
startdate DATETIME,
enddate DATETIME
);
INSERT INTO @testtable
(
uid,
startdate,
enddate
)
VALUES
(1233890,'01-Jul-2017 00:00:00','15-Jul-2017 23:59:59'),
(1523420,'01-Jul-2018 00:00:00','15-Jul-2018 23:59:59')
SELECT UID, [DATE], [WAKEUP_TIME]
FROM dbo.USERS user
INNER JOIN @testtable cont
ON user.uid = cont.uid
AND user.DATE >= cont.startdate
AND user.DATE <= cont.enddate
WHERE user.USER_NAME = 'John'
ORDER BY 2 ;