Работа с огромной таблицей - 100 миллионов строк - PullRequest
0 голосов
/ 24 августа 2018

У меня есть таблица с примерно 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):

Упражнения на тренировку:

  1. TreningId (также FK)
  2. ExerciseId (также FK)

Обучение:

  1. UserId (также FK)
  2. AllRoutinesId (также FK)
  3. Score
  4. 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% случаев мне нужны данные, которым меньше года.Каковы мои лучшие варианты относительно запросов и размера таблицы?

Мои мысли о запросах:

  1. Создание индексированного представления ИЛИ
  2. Добавление полей Date и UserId в таблицу TreningExerciseId ИЛИ
  3. Некоторые параметрыо чем я не думал:)

Что касается размера таблицы, либо:

  1. Таблица разделов (вероятно, по дате) ИЛИ
  2. Переместить большую частьданные (или все это) в какое-то хранилище значений ключей NoSQL ИЛИ
  3. Какой-то вариант, о котором я не задумывался:)

Что вы думаете об этих проблемах,как мне подойти к их решению?

1 Ответ

0 голосов
/ 24 августа 2018

Если добавить следующие столбцы в индекс «ix_TreninID»:

  • NoOfRepsForExecercise
  • ExerciseID
  • RoutineExerciseID

Тосделает индекс «покрывающим индексом» и устранит необходимость в поиске, который занимает 95% плана.

Попробуйте и отправьте ответ.

...