2015-09-03 1 views
0

У меня довольно хлопотное таблицу, которая выглядит следующим образом:SQL-таблица со многими конкретными датами. Как сделать это более масштабируемым?

EventTimeLog

Id (bigint) | Time (datetime) | LogId (FK to Log tables Id column) 

Эта таблица показывает времена произошло событие Log. Таким образом, можно записать только одно уникальное событие журнала и разывать эти журналы из этой таблицы.

Проблема в том, что даты являются настолько конкретными, и эти даты могут иметь повторяющиеся значения. Пример:

2015-08-03 23:54:58.000 | 1983 
2015-08-03 23:54:58.000 | 1934 
2015-08-03 23:54:56.000 | 1647 

Через некоторое время он становится очень трудно запросить. Обычно около 500 тыс. Строк или около того начинается раскручивание, даже если я ставлю индекс в LogId и Time. К тому времени, когда я попал в диапазон 1 м и выше, запросы замедляются до обхода ...

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

Я не уверен, как сделать эту таблицу более масштабируемой. Может быть, разбить это на ежемесячные таблицы?

В соответствии с просьбой, вот запрос используется, который начинает урчание

SELECT b.User, b.Ip, b.AccountId, a.Time FROM 
EventTimeLog a 
inner join [Log] b on a.LogId = b.Id 
WHERE 
b.UserId = '<param>' AND 
a.Time >= '<param>' AND 
a.Time <= '<pamam>' 

Если разница во времени> 2 дня он пыхтит, как сумасшедший. И да, у меня есть индексы в Log for UserId.

+1

Почему эта информация отсутствует в таблицах журналов? – Paolo

+2

500K строк, и ваш запрос начинает прерываться, хммм, вы посмотрели на счетчики ресурсов? память и процессор и т. д. ...500K строк с тремя столбцами на самом деле не большая таблица, сервер sql с разумными ресурсами должен иметь возможность обрабатывать его довольно красиво. –

+0

Можете ли вы показать нам запрос, который становится настолько медленным? –

ответ

0

В вашем столе много раз несколько отличающихся друг от друга. Это сделало бы индекс огромным и не очень полезным.

Поэтому рассмотрите вычисленный столбец, вместо этого давая вам менее точное время. Затем создайте индекс для logid + этот вычисленный столбец.

Я не знаю, в какие промежутки времени вы обычно запрашиваете. Давайте используем часы для примера. Вы бы укоротить дату в час (например, dateadd(hour, datediff(hour, 0, time), 0) или в виде строки: substring(convert(varchar(25), time, 120), 1, 13)):

новый столбец (я использую строку здесь):

alter table mytable add comp_hour as substring(convert(varchar(25), time, 120), 1, 13); 

Так вы получите, например:

 
time       comp_hour 
2015-09-03 14:12:10.2158145  '2015-09-03 14' 
2015-09-03 14:45:27.4457813  '2015-09-03 14' 

индекс:

create index index_comp_hour on mytable(logid, comp_hour); 

запрос:

select l.user, l.ip, l.accountid, e.time 
from log l 
join eventtimelog e on e.logid = l.id and e.comp_hour in ('2015-09-03 13', '2015-09-03 14') 
where l.userid = 123; 

(я не уверен, хотя, будь то индекс mytable(logid, comp_hour) или mytable(comp_hour, logid) бы лучше, или если она даже имеет значение. Вы можете просто создать оба варианта, а затем посмотреть план выполнения и удалить тот, который не используется.)

+0

Это очень хорошая идея! Я должен попробовать это. – user2326106

+0

Извините, так долго было, чтобы вернуться к вам. Казалось, это трюк. Для этого добавлен новый столбец TimeAggregate. Затем сбросили и переделали индекс в LogId и TimeAggregate, а также столбец Include on the Time. Сократите время вниз резко! – user2326106

Смежные вопросы