Процедура вставки нескольких строк SQL Server после проверки, не существуют ли они — как я могу улучшить свою производительность?

#c# #sql-server #bulkinsert

#c# #sql-server #bulkinsert

Вопрос:

У меня есть таблица базы данных sql server 2008, которая содержит ссылки на статьи. Моя процедура приложения заключается в том, что каждые ~ 1-10 секунд я получаю список из 10-100 новых статей, содержащих URL-адрес, и что мне нужно сделать, это проверить URL-адрес каждой статьи, и если он не существует в БД, я добавлю его.

Как я это знаю: первое — я создал уникальный индекс для URL, поэтому, несмотря ни на что, у меня не будет одного и того же URL более одного раза (конечно, я нормализую url, например, сокращаю его ‘http://www .’префикс и т.д., прежде чем я его вставлю).

метод ‘InsertArticles’ выглядит примерно так:

  1. Открыть транзакцию
  2. для каждой ссылки — проверьте (используя транзакцию), существует ли ее URL-адрес в БД
  3. для каждой несуществующей ссылки — добавьте ссылку (конечно, используя ту же транзакцию)
  4. выполнить и закрыть транзакцию обработать транзакцию / общие исключения

дело в том, что в большинстве случаев он работает очень быстро (0,05-0,2 секунды) примерно для 10-20 или около того ссылок.. но иногда это становится намного медленнее — вызов этого метода с 50 статьями может занять даже 50 секунд.

Итак, здесь 2 вопроса —

  1. то, что я делаю, нормально? должен ли я использовать транзакции для такого рода работы?
  2. какие альтернативы у меня есть? может быть, вставить, если не существует?

я также подумал — почему бы просто не «грубо вставить» новые статьи в БД — это означает, что я попытаюсь вставить все входные URL-адреса в БД, и я позволю sql server создать исключение для тех URL-адресов, которые там уже существуют..

Возможно, использование сохраненного процесса для выполнения всего этого может повысить производительность?

в любом случае, любая помощь будет оценена.

Комментарии:

1. sergeyv.com/blog/archive/2010/09/10/…

Ответ №1:

Вы можете попробовать оператор СЛИЯНИЯ, чтобы объединить SELECT и INSERT в один оператор:

 -- Table "links" with column "url"
MERGE links AS L
USING (SELECT url FROM links WHERE url = @url) AS I (url)
ON (L.url = I.url)
WHEN NOT MATCHED THEN INSERT (url) VALUES (@url)