На работе мы создаем большие многостраничные веб-приложения, состоящие в основном из радио и флажков. Основная цель каждого приложения - сбор данных, но когда пользователи возвращаются на страницу, которую они посетили ранее, мы сообщаем им их предыдущие ответы. В худшем случае, у нас может быть до 900 различных переменных и около 1,5 миллионов пользователей.
По нескольким причинам имеет смысл использовать подход «только вставка» для хранения данных (в отличие от обновления на месте), чтобы мы могли фиксировать исторические данные о повторных взаимодействиях с переменными. В результате мы можем получить несколько ответов на пользователя для каждой переменной.
Наша таблица для сбора ответов выглядит примерно так:
CREATE TABLE [dbo].[results](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[userid] [int] NULL,
[variable] [varchar](8) NULL,
[value] [tinyint] NULL,
[submitted] [smalldatetime] NULL)
Где id служит первичным ключом.
Практически каждый запрос приводит к серии операторов вставки (по одному на каждую переданную переменную), а затем мы запускаем команду select для получения предыдущих ответов для следующей страницы (что-то вроде этого):
SELECT t.id, t.variable, t.value
FROM results t WITH (NOLOCK)
WHERE t.userid = '2111846' AND
(t.variable='internat' OR t.variable='veteran' OR t.variable='athlete') AND
t.id IN (SELECT MAX(id) AS id
FROM results WITH (NOLOCK)
WHERE userid = '2111846' AND (t.variable='internat' OR t.variable='veteran' OR t.variable='athlete')
GROUP BY variable)
Который в этом случае будет возвращать самые последние ответы для переменных "internat", "veteran" и "athlete" для пользователя 2111846.
Мы следовали советам инструментов настройки базы данных при индексации таблиц, и, по нашим данным, это наиболее эффективная версия запроса на выборку, которую нам удалось найти. Несмотря на это, кажется, что при приближении к 1 миллиону записей наблюдается значительное снижение производительности (а это может быть примерно в 150 раз). У нас есть довольно элегантное решение для разделения данных между несколькими таблицами, которое работает довольно хорошо, но я открыт для любых советов о том, как я могу построить лучшую версию запроса select. Мы часто используем эту структуру для хранения большого количества независимых точек данных, и нам нравятся ее преимущества.
Итак, вопрос в том, как я могу улучшить производительность запроса select? Я полагаю, что вложенное выражение select - плохая идея, но мне еще предстоит найти альтернативу, которая также хорошо работает.
Заранее спасибо.
NB. Поскольку в этом случае мы подчеркиваем создание избыточного чтения и поскольку мы никогда не обновляемся на месте, кажется, что нет никакого наказания (и некоторого преимущества) за использование директивы NOLOCK в этом случае.