Совет для уменьшения соединяющего добавления только таблицы в SQL Server MS?

Возможно, это не связано, но я заметил, что в некоторых тестах, которые я проводил сегодня, мои юнит-тесты, казалось, работали медленнее и медленнее. Случайно я вышел из / перезапустил Visual Studio, и мои тесты теперь намного быстрее. В механизме модульного тестирования может быть какая-то утечка памяти или другие проблемы с ресурсами. Я запускаю обновление 1.

9
задан Cœur 21 October 2018 в 06:57
поделиться

4 ответа

Вставка обычной транзакции (т.е. READ COMMITTED) уже выполняет «минимальную» блокировку. Приложения с интенсивной вставкой не будут блокировать вставку, независимо от того, в каком порядке вставка смешивается с другими операциями. В худшем случае, интенсивная система вставки может вызвать конкуренцию за защелку страницы в горячей точке, где происходит вставка, но не может вызвать взаимоблокировки.

Чтобы вызвать взаимоблокировки, как описано Джеффом, должно быть что-то большее, например, любое из следующего:

  • ] Система использует более высокий уровень изоляции (они уже тогда это сделали, и они это заслужили)
  • Они читали из таблицы журнала во время транзакции (так что больше не «только для добавления»)
  • Цепочка взаимоблокировок задействованные блокировки прикладного уровня (например, операторы .Net lock в структуре log4net), приводящие к необнаруживаемым взаимоблокировкам (т.е. приложение зависает). Учитывая, что решение проблемы заключалось в просмотре дампов процессов, я предполагаю, что это был тот сценарий, который они имели.

Так что, пока вы вставляете только регистрацию в транзакции уровня изоляции READ COMMITTED, вы в безопасности. Если вы ожидаете той же проблемы, которая, как я подозреваю, была у SO (т. Е. Тупиковые ситуации, связанные с блокировками на уровне приложений), то никакое количество волшебных средств базы данных не может вас спасти, поскольку проблема все равно может проявиться, даже если вы входите в отдельную транзакцию или в отдельное соединение.

5
ответ дан 4 December 2019 в 19:35
поделиться

Поскольку вы не заботитесь о транзакционной целостности таблицы аудита, вы, очевидно, можете вести журнал вне транзакции (то есть после ее завершения). Это минимизирует влияние на транзакцию.

Кроме того, если вы хотите минимизировать блокировку, вы должны попытаться убедиться, что как можно большая часть вашей рабочей нагрузки запросов покрывает некластеризованные индексы. (SQL Server 2005 и более поздние версии, использование оператора INCLUDE в индексах NC может иметь большое значение)

1
ответ дан 4 December 2019 в 19:35
поделиться

Один из простых способов предотвратить возникновение проблем с блокировкой при ведении журнала с «обычной» базой данных - это не использовать одну и ту же базу данных. Просто создайте еще одну базу данных для ведения журнала. В качестве бонуса быстрый рост вашей базы данных журналов не приведет к фрагментации вашей основной БД. Лично я обычно предпочитаю вести журнал в файл - но опять же, я привык выполнять тяжелые манипуляции с текстом в своем редакторе - VIM. Ведение журнала в отдельную базу данных должно помочь избежать проблем с взаимоблокировкой.

Просто убедитесь, что если вы попытаетесь написать собственный прикладник базы данных для используемой вами инфраструктуры ведения журнала, вы будете очень осторожны со своими блокировками (я предполагаю, что это то, что привело Джеффа в сообщении блога, на которое вы ссылаетесь). Правильно написано (см. Несколько комментариев в сообщении Джеффа), вы не должны

1
ответ дан 4 December 2019 в 19:35
поделиться

If you don't care about consistency on your logging table, why not perform all the logging from a separate thread.

I probably would not wait for transactions to complete before logging, since the log can be pivotal in diagnosing long running transactions. Also, this enables you to see all the work a transaction that rolled back did.

Grab the stack trace and all of your logging data in the logging thread, chuck it on a queue when there are new logging messages, flush them to the db in a single transaction.

Steps to minimizing locking:

  • (KEY) perform all appends to the logging table outside of the main thread/connection/transaction.
  • Ensure your logging table has a monotonically increasing clustered index (Eg. int identity ) that is increasing each time you append a log message. This ensures the pages being inserted into are usually in memory and avoids the performance hits you get with heap tables.
  • Perform multiple appends to the log in a transaction (10 inserts in a transaction are faster than 10 inserts out of a transaction and usually acquire/release less locks)
  • Give it a break. Only perform logging to your db every N milliseconds. Batch up bits of works.
  • If you need to report on stuff historically, you can consider partitioning your logging table. Example: You could create a new logging table every month, and at the same time have a log VIEW that is a UNION ALL of all the older logging tables. Perform the reporting against the most appropriate source.

You will get better performance by flushing multiple logging messages in a single (smallish) transaction, and have the advantage that if 10 threads are doing work and logging stuff, only a single thread is flushing stuff to the logging table. This pipelining actually makes stuff scale better.

5
ответ дан 4 December 2019 в 19:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: