Другой способ выбрать количество (отличный идентификатор пользователя) из таблицы? - PullRequest
0 голосов
/ 20 июля 2009

Есть ли более быстрый способ выбрать различное количество пользователей из таблицы? Возможно, используя row_number, разбиение или перекрестное применение?

Я просто не могу сейчас об этом думать.

Пример:

Table UsageLog

UserId     Date     StoreNumber
Alice      200901   342
Alice      200902   333
Alice      200902   112
Bob        200901   112
Bob        200902   345
Charlie    200903   322

Вот мой текущий запрос:

select count(distinct userID), date
from
   UsageLog
where
   date between 200901 and 200902
group by date

Моя фактическая таблица содержит миллионы строк, и все столбцы на самом деле являются целыми числами.

Есть ли более быстрый способ получить список пользователей?

Редактировать

У меня уже есть некластеризованные индексы для всех отдельных столбцов. По какой-то причине план выполнения показывает, что я все еще выполняю сканирование таблицы. Я думаю, я должен создать кластерный индекс по дате. Я посмотрю, как это работает ...

Ответы [ 6 ]

3 голосов
/ 20 июля 2009

В целом, я не нашел способа быстрее, чем у вас, COUNT (DISTINCT UserId) - довольно простой запрос.

Ваша самая важная вещь здесь - убедиться, что у вас есть индекс для таблицы, который работает для столбца «Дата» и столбца UserId

2 голосов
/ 20 июля 2009

SELECT DISTINCT () - это путь. Проблема заключается в том, что вы достигли критической точки date индекса , поэтому вместо этого ваш план идет на сканирование кластерного индекса. Смотрите ссылку на статью Кимберли Л. Триппа, что такое «переломный момент».

Вам нужен индекс покрытия:

CREATE INDEX idx_UsageLog_date_user_id ON UsageLog(date) INCLUDE (userID);

Кластерный индекс также будет работать, но имеет и другие побочные эффекты. Если кластерный индекс на date в порядке с остальными вашими шаблонами доступа к данным, то он лучше, чем предлагаемый мной покрывающий индекс.

Обновление:

Индекс обратного порядка, который вы пробовали на (userID, date), также работает, будет искать каждый идентификатор пользователя. На самом деле это лучше, чем (date, userID) или (date) INCLUDE (userID), поскольку он возвращает предварительно отсортированные идентификаторы пользователя, поэтому DISTINCT не вводит дополнительную сортировку.

Тем не менее, я рекомендую перейти по ссылке, которую я разместил, чтобы понять, почему «индекс по каждому отдельному столбцу» не помог.

2 голосов
/ 20 июля 2009

Составной индекс для Date и UserId должен немного помочь

1 голос
/ 20 июля 2009

Я провел несколько быстрых тестов.

Один индекс для Date и UserID: план выполнения показывает поиск по индексу, но затем сортировку для выполнения различного, что является медленным.

Один индекс для идентификатора пользователя и даты: план выполнения показывает сканирование индекса и два вычисления, что приводит к снижению стоимости всех сценариев, которые я запускал.

Другие сценарии только с Date или UserID с индексом стоят дороже, чем предыдущий.

1 голос
/ 20 июля 2009

используйте GROUP BY и убедитесь, что у вас есть индекс для столбца UserId

0 голосов
/ 20 июля 2009

Вы пробовали группировать по?

например:

select count(userID), userID
  from UsageLog
 where date between 200901 and 200902
Group by userID

Затем составьте план объяснения для обоих показателей.

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