Как написано в моем вопросе, у меня есть проблема с моим планом выполнения, как вы можете видеть из заголовка: группа запросов, выполнение которых занимало около 30-40 секунд, теперь включила этот раздел в план выполнения:
![Costly part](https://i.stack.imgur.com/XWh2o.png)
В то время как план выполнения этой части был таким до сегодняшнего утра:
![enter image description here](https://i.stack.imgur.com/bgHWi.png)
Знаете ли вы, что могло вызвать это, когда ни одна из задействованных таблиц не изменилась существенно?
Еще немного подробный контекст : на работе у нас разные .csv
от разных поставщиков, которые содержат все продукты, которые они могут нам продать со всеми данными, которые нам могут понадобиться.
Поскольку мы очень часто используем только часть данных (ProductName
, BrandId
, Price
, Availability
), и каждый поставщик форматирует свои данные по-разному, мы извлекаем данные из .csv
в нашу базу данных SQL Server, а затем мы объединяем данные из этих вложенных таблиц (от 5 до 200 тысяч строк) в нашу основную таблицу (около 1500 тысяч строк).
Упрощенный запрос очень похож на этот для всех наших процедур:
У нас есть первая часть, выбирающая из подтаблиц данные, чтобы получить общую структуру, которую я действительно могу загрузить в свою базу данных. На этом этапе могут быть применены некоторые фильтры.
WITH query(Supplier, ProductCode, Brand, Price, RefreshDate, Quantity) AS
(
SELECT
'SUPPLIERANAME' AS Supplier,
supplierData.ProductCode AS ProductCode,
catalogo_mapping_produttori.nome AS Brand,
supplierData.Price AS Price,
GETDATE() AS RefreshDate,
supplierData.Quantity AS Quantity
FROM
SupplierA_Table AS supplierData
)
Затем я просто объединяю эти данные с моей основной таблицей:
MERGE Catalogo_Offerte AS T
USING query AS S
ON (T.ProductCode = S.ProductCode AND T.Brand = S.Brand AND T.Supplier = S.Supplier)
WHEN MATCHED
THEN UPDATE
SET
T.Price = S.Price,
T.RefreshDate = S.RefreshDate,
T.Quantity = S.Quantity
WHEN NOT MATCHED BY TARGET
THEN INSERT(Supplier, ProductCode, Brand, Price, RefreshDate, Quantity)
VALUES(S.Supplier, S.ProductCode, S.Brand, S.Price, S.RefreshDate, S.Quantity)
-- We allow some tolerance before deleting
WHEN NOT MATCHED BY SOURCE AND T.RefreshDate <= DATEADD(dd, -7, GETDATE())
THEN DELETE;
Я могу редактировать при необходимости больше данных, и заранее благодарю всех, кто нашел время, чтобы ответить и обсудить вопрос.
Edit # 1 : план запроса, к сожалению, является планом после того, как нам пришлось восстанавливать БД во второй раз, так что это не представляет проблемы, к сожалению:
https://www.brentozar.com/pastetheplan/?id=SJqOL2lTz
Об индексах: главная таблица работает с (ProductCode, Brand, Supplier) как уникальный индекс, у нас также есть индекс идентификационного ключа, который не отображается в таблице, и именно в этом случае спул, как кажется, происходит сейчас, когда я обратите внимание.
Что касается вложенных таблиц, у которых разные индексы, то для некоторых из них настроен тип автоинкрементного ключа, установленного поставщиком, в то время как для других у нас есть идеальный ключ (brand, productCode). В основном мы получаем эти два случая, очевидно, что в первом случае нам необходимо нормализовать данные, чтобы сделать их совместимыми с нашей системой.