У меня есть API, который получает большой объект JSON (минимум 7 МБ), этот JSON состоит из следующих вложенных объектов:
[
{
"CategoryId": "P1",
"CategoryName": "Pizza",
"Products": [
{
"ProductId": "PROD700",
"ProductName": "Pepperoni Feast Large",
"ProductPrice": "5.5",
"Choices": [
{
"CoiceId": "CH22",
"ChoiceName": "Crust",
"Extras": [
{
"ExtraId": "EX1",
"ExtraName": "Classic Hand Tossed",
"ExtraPrice": "1"
},
{
"ExtraId": "EX2",
"ExtraName": "Crunchy Thin Crust",
"ExtraPrice": "1.25"
}
]
},
{
"CoiceId": "CH24",
"ChoiceName": "Additionals",
"Extras": [
{
"ExtraId": "EX3",
"ExtraName": "Extra Black Olives",
"ExtraPrice": "0.325"
},
{
"ExtraId": "EX4",
"ExtraName": "Extra Jalapeno",
"ExtraPrice": "0.4"
}
]
}
]
}
]
}
]
Этот API получит JSON и сохранит его вочереди, пока другая фоновая служба (то есть консольное приложение или служба Windows) не использует тот же API для чтения и не получит список запросов PENDING для записи в базу данных.
Фактически это был очень типовой объект,но я просто хотел поделиться идеей и структурой этого объекта, и у меня есть монолитная база данных, которая имеет огромный трафик в секунду, поэтому у меня были следующие варианты:
- Наличие некоторыхвложенные циклы для сохранения вышеуказанных данных по одному в базе данных, что я считаю слишком плохим, и это приведет к снижению производительности базы данных из-за большого количества циклов, кроме того, это займет слишком много времени, чтобы сделать это.
- Используя предыдущий сценарий, но с параллелизмом, мы можем иметь тот же сценарий с чем-то вроде
Parallel.For
или около того, чтобы сократить время выполнениянасколько я могу, но у нас все еще есть проблема многих обращений к базе данных. - Чтобы преодолеть 2 вышеупомянутых проблемы (время выполнения и многочисленные обращения к базе данных), я подумал об использовании концепции промежуточных таблиц вместе с
SqlBulkCopy
Таким образом, у нас может быть несколько промежуточных таблиц в основной базе данных или tempdb
, тогда после вставки / массового копирования у меня может быть хранимая процедура, которая имеет оператор MERGE
, который будет вставлять данные из этих промежуточных таблиц в основные таблицы в базе данных.,Основная проблема здесь, если консольное приложение обрабатывает более одного запроса / объекта одновременно, это будет проблемой, поскольку промежуточная таблица будет заблокирована во время SqlBulkCopy
, кроме того, удаление индексов из этой промежуточной таблицы приведет кво время процесса копирования было бы лучше максимально ускорить его, но до MERGE
у нас должны быть индексы, чтобы ускорить процесс чтения из этих промежуточных таблиц.Здесь возникает проблема с индексами CREATE
& DROP
, это слишком сложно и не рекомендуется, особенно в 2 случаях: в промежуточной таблице (1) содержится большой объем данных. (2) что, если я начал создавать индексы в качестве подготовки к MERGE
, но между тем идет еще один SqlBulkCopy
параллельно для другого запроса.
В чем вопрос?речь идет об архитектуре приложения ... Просто я хочу выполнить процесс записи в базу данных, не снижая при этом производительность базы данных и не тратя много ресурсов как на серверы приложений, так и на базы данных.Кроме того, я хочу решить проблемы, о которых я упоминал выше, в предлагаемых сценариях, таких как время выполнения и множество циклических обходов для таблиц БД и блокировок, в то время как SqlBulkCopy в случае одновременных запросов.
Я просто делюсь своимиМысли об этом, но я полностью готов услышать от вас, если у вас есть лучшая идея / реализация для этого сценария.
ПРИМЕЧАНИЯ :
- Яиспользование
ADO .NET
вместе с хранимыми процедурами для ускорения всего процесса. - Каждый запрос должен быть записан в базу данных в течение максимум 5-10 минут с момента ее создания / публикации.
- Иногдау нас может быть несколько запросов, которые должны быть написаны параллельно, и последовательная обработка не будет хорошей с точки зрения бизнеса.