У меня есть таблица с примерно 100 миллионами строк, и она только увеличивается, так как к таблице обращаются довольно часто, мне нужно придумать какое-то решение для ее оптимизации.
Во-первых, здесь модель:
CREATE TABLE [dbo].[TreningExercises](
[TreningExerciseId] [uniqueidentifier] NOT NULL,
[NumberOfRepsForExercise] [int] NOT NULL,
[CycleNumber] [int] NOT NULL,
[TreningId] [uniqueidentifier] NOT NULL,
[ExerciseId] [int] NOT NULL,
[RoutineExerciseId] [uniqueidentifier] NULL)
Таблица треннинга:
CREATE TABLE [dbo].[Trenings](
[TreningId] [uniqueidentifier] NOT NULL,
[DateTimeWhenTreningCreated] [datetime] NOT NULL,
[Score] [int] NOT NULL,
[NumberOfFinishedCycles] [int] NOT NULL,
[PercentageOfCompleteness] [int] NOT NULL,
[IsFake] [bit] NOT NULL,
[IsPrivate] [bit] NOT NULL,
[UserId] [nvarchar](128) NOT NULL,
[AllRoutinesId] [bigint] NOT NULL,
[Name] [nvarchar](max) NULL,
)
Индексы (кроме кластеризованных PK):
Упражнения на тренировку:
- TreningId (также FK)
- ExerciseId (также FK)
Обучение:
- UserId (также FK)
- AllRoutinesId (также FK)
- Score
- DateTimeWhenTreningCreated (упорядочено по DateTimeWhenTreningCreated DESC)
А вот пример наиболее часто выполняемый запрос :
DECLARE @userId VARCHAR(40)
,@exerciseId INT;
SELECT TOP (1) R.[TreningExerciseId] AS [TreningExerciseId]
,R.[NumberOfRepsForExercise] AS [NumberOfRepsForExercise]
,R.[TreningId] AS [TreningId]
,R.[ExerciseId] AS [ExerciseId]
,R.[RoutineExerciseId] AS [RoutineExerciseId]
,R.[DateTimeWhenTreningCreated] AS [DateTimeWhenTreningCreated]
FROM (
SELECT TE.[TreningExerciseId] AS [TreningExerciseId]
,TE.[NumberOfRepsForExercise] AS [NumberOfRepsForExercise]
,TE.[TreningId] AS [TreningId]
,TE.[ExerciseId] AS [ExerciseId]
,TE.[RoutineExerciseId] AS [RoutineExerciseId]
,T.[DateTimeWhenTreningCreated] AS [DateTimeWhenTreningCreated]
FROM [dbo].[TreningExercises] AS TE
INNER JOIN [dbo].[Trenings] AS T ON TE.[TreningId] = T.[TreningId]
WHERE (T.[UserId] = @userId)
AND (TE.[ExerciseId] = @exerciseId)
) AS R
ORDER BY R.[DateTimeWhenTreningCreated] DESC
План выполнения: ссылка
Пожалуйста, примите мои извинения, если он не читается илинеоптимизированный, он был сгенерирован ORM (Entity Framework), я просто немного его отредактировал.
Согласно инструменту SQL Analytics Azure этот запрос оказывает наибольшее влияние на мою БД, и, хотя обычно он не занимает много времени, время от времени возникают пики в операциях ввода-вывода из-за этого.
Кроме того, для упрощения используется небольшая бизнес-логика: в 99% случаев мне нужны данные, которым меньше года.Каковы мои лучшие варианты относительно запросов и размера таблицы?
Мои мысли о запросах:
- Создание индексированного представления ИЛИ
- Добавление полей Date и UserId в таблицу TreningExerciseId ИЛИ
- Некоторые параметрыо чем я не думал:)
Что касается размера таблицы, либо:
- Таблица разделов (вероятно, по дате) ИЛИ
- Переместить большую частьданные (или все это) в какое-то хранилище значений ключей NoSQL ИЛИ
- Какой-то вариант, о котором я не задумывался:)
Что вы думаете об этих проблемах,как мне подойти к их решению?