У меня есть 2 файла, которые я хотел бы импортировать в MS SQL. Первый файл имеет размер 2,2 ГБ, а второй - 24 ГБ. (если вам интересно: это справочная таблица по покеру)
Импортировать их в MS SQL не проблема. Благодаря SqlBulkCopy я смог импортировать первый файл всего за 10 минут. Моя проблема в том, что я не знаю, как должна выглядеть фактическая схема таблицы, чтобы позволить мне выполнять очень быстрые запросы. Моя первая наивная попытка выглядит так:
CREATE TABLE [dbo].[tblFlopHands](
[hand_id] [int] IDENTITY(1,1) NOT NULL,
[flop_index] [smallint] NULL,
[hand_index] [smallint] NULL,
[hs1] [real] NULL,
[ppot1] [real] NULL,
[hs2] [real] NULL,
[ppot2] [real] NULL,
[hs3] [real] NULL,
[ppot3] [real] NULL,
[hs4] [real] NULL,
[ppot4] [real] NULL,
[hs5] [real] NULL,
[ppot5] [real] NULL,
[hs6] [real] NULL,
[ppot6] [real] NULL,
[hs7] [real] NULL,
[ppot7] [real] NULL,
[hs8] [real] NULL,
[ppot8] [real] NULL,
[hs9] [real] NULL,
[ppot9] [real] NULL,
CONSTRAINT [PK_tblFlopHands] PRIMARY KEY CLUSTERED
(
[hand_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Индекс флопа - это значение от 1 до 22100 (первые 3 общие карты в техасском холдеме, 52 выбирают 3). Каждый индекс флопа имеет индекс hand_index от 1 до 1176 (49 выбирают 2). Таким образом, в этой таблице 25 989 600 строк.
Выполнение запроса с моей приведенной выше «схемой» заняло ок. 25 секунд После некоторого поиска в Google я обнаружил, что сервер SQL выполняет сканирование таблицы, что, очевидно, является плохой вещью. Я запустил «Помощник по настройке ядра СУБД», и он порекомендовал создать индекс для столбца flop_index (имеет смысл). После создания индекса необходимые дисковые пространства для БД удвоились! (плюс файл журнала LDF вырос на 2,6 ГБ)
Но после индексации запрос занял всего пару мс.
Теперь мой вопрос: как мне сделать это правильно? Я никогда не работал с такими массивными данными, базы данных, которые я создал ранее, были шуткой.
Некоторые вещи, на которые следует обратить внимание: после импорта данных в MS SQL никогда не будет вставки или обновления данных, просто выберите их. Поэтому мне интересно, нужен ли мне хотя бы первичный ключ?
РЕДАКТИРОВАТЬ: Я предоставляю дополнительную информацию, чтобы сделать мой вопрос более ясным:
1) Я никогда не буду использовать hand_id. Я положил его туда только потому, что кто-то давным-давно сказал мне, что я должен всегда создать первичный ключ для каждой таблицы.
2) Я буду использовать только один запрос:
SELECT hand_index, hs1, ppot1, hs2, ppot2, hs3, ppot3, hs4, ppot4, hs5, ppot5, hs6, ppot6, hs7, ppot7, hs8, ppot8, hs9, ppot9 WHERE flop_index = 1...22100
Этот запрос всегда будет возвращать 1176 строк с нужными мне данными.
EDIT2: Просто чтобы быть более конкретным: да, это статические данные. У меня есть эти данные в двоичном файле. Я написал программу для запроса этого файла с данными, которые мне нужны всего за несколько миллисекунд. Причина, по которой мне нужны эти данные в базе данных, заключается в том, что я хочу иметь возможность запрашивать данные с разных компьютеров в моей сети без необходимости копировать 25 ГБ на каждый компьютер.
HS означает ручную силу, он показывает текущую силу руки ваших закрытых карт в сочетании с картами флопа или терна. ppot означает положительный потенциал, это шанс, что ваша рука будет впереди после раздачи следующей общей карты. hs1 до 9 - это сила руки против 1 до 9 противников. То же самое для ppot. Вычисление ppot на лету требует очень много времени и занимает несколько минут. Я хочу создать программу анализа покера, которая дает мне список всех возможных комбинаций хоул-карт на любом флопе / ходу с их hs / ppot.