Каков самый быстрый способ сделать это:
- Одна таблица, никаких ссылок, которые я не могу предварительно заполнить (т.е. там есть один ссылочный ключ, но у меня есть все заполненные данные)
- Количество данных. Мы говорим о сотнях миллионов строк в день, динамически вступая через API
- Запросы должны/должны быть обработаны как можно скорее в сценарии почти реального времени (т.е. не выписывать файл для загрузки в день). 2 секунды - это нормальная максимальная задержка
- Отдельные машины для данных/приложений и SQL Server
Что я делаю сейчас:
- Совокупность до 32 * 1024 строк в массиве, а затем очередь.
- Прочитайте очередь в 2-3 потоках. Вставьте в базу данных с помощью SqlBulkCopy.
Я получаю около 60k-75k строк, импортированных в секунду, чего недостаточно, но довольно близко. Я хотел бы поразить 250 000 строк.
Пока ничего не используется. Я получаю 20-процентные блоки "сетевого ввода-вывода", имеют одну базовую 80-процентную загрузку процессора. Диски пишут 7mb-14mb, в основном бездействуют. Средняя длина очереди на RAID 10 из 6 raptors составляет.... 0.25.
Кто-нибудь знает, как ускорить это? Более быстрый сервер (до сих пор он виртуальный, 8 ГБ оперативной памяти, 4 ядра, физический диск для передачи данных).
Добавление некоторых пояснений:
- Это корпоративный SQL Server 2008 R2 на сервере 2008 R2. машина имеет 4 ядра, 8 гб баранов. Все 64 бит. 80% нагрузки приходится на эту машину, показывающую нагрузку около 20% cpu.
- Таблица проста, не имеет первичного ключа, только индекс реляционной ссылки (ссылка на инструмент) и уникальный (в пределах набора инструментов, поэтому это не соблюдается) отметка времени.
- Полями таблицы являются: отметка времени, ссылка на инструмент (без принудительного внешнего ключа), тип данных (char 1, одно из нескольких символов, указывающих, какие данные публикуются), цена (двойной) и объем (int). Как вы можете видеть, это ОЧЕНЬ тонкий стол. Данные, о которых идет речь, являются тиковыми данными для финансовых инструментов.
- Вопрос также в том, что касается аппаратного обеспечения и т.д. - в основном потому, что я не вижу реального узкого места. Я вставляю несколько транзакций, и это дает мне преимущество, но мало. Диски, CPU не показывают значительную нагрузку, сетевой io-ожидания высоки (300 мс/секунду, 30% на данный момент), но это на той же платформе виртуализации, которая запускает JSUT на двух серверах и имеет достаточно ядер для запуска всех. Я в значительной степени открыт для "покупки другого сервера", но сначала хочу определить узкое место... особенно учитывая, что в конце дня я не разбираюсь в узком месте. Ведение журнала не имеет значения - объемные вставки НЕ входят в журнал данных как данные (без кластеризованного индекса).
Помогло ли вертикальное разбиение на разделы, например, байтом (tinyint), который разделил бы юниверс инструмента, например, на 16 таблиц, и, таким образом, я сделал до 16 вставок одновременно? Поскольку на самом деле данные поступают из разных обменов, я могу сделать раздел на обмен. Это было бы естественным полем разделения (которое фактически является инструментом, но я мог бы дублировать эти данные здесь).
Еще несколько пояснений: скорость еще выше (90k), теперь явно ограничена сетью IO между машинами, что может быть переключением VM.
Теперь я делаю соединение на 32 тыс. строк, размещаю временную таблицу, вставляю в нее с помощью SqlBUlkdCopy, ТОЛЬКО использую ОДИН SQL-оператор для копирования в основную таблицу - сводит к минимуму любое время блокировки в главной таблице.
В большинстве случаев время ожидания остается в сети IO. Кажется, я сталкиваюсь с проблемами, когда VM мудрый. Переместится на физическое оборудование в следующие месяцы;)