ВЫБОР SQL Server В и блокирующийся с временными таблицами

Что относительно того, чтобы использовать дополнительный метод?

<час>
public static class StringExtensions
{
   public static string Repeat(this char chatToRepeat, int repeat) {

       return new string(chatToRepeat,repeat);
   }
   public  static string Repeat(this string stringToRepeat,int repeat)
   {
       var builder = new StringBuilder(repeat*stringToRepeat.Length);
       for (int i = 0; i < repeat; i++) {
           builder.Append(stringToRepeat);
       }
       return builder.ToString();
   }
}
<час>

Вы могли затем записать:

Debug.WriteLine('-'.Repeat(100)); // For Chars  
Debug.WriteLine("Hello".Repeat(100)); // For Strings

Примечание, что тест производительности использования stringbuilder версии для простых символов вместо строк дает Вам главный проступок производительности: на моем компьютере разница в mesured производительности 1:20 между: Отладка. WriteLine ('-'.Repeat (1000000))//символьная версия и
Отладка. WriteLine (" - ".Repeat (1000000))//представляют версию

в виде строки
26
задан Mitchel Sellers 19 August 2009 в 21:24
поделиться

6 ответов

Этот совет давно витает вокруг :

Узкие места в SQL Server 6.5

Многие люди используют запрос SELECT ... INTO чтобы создать временную таблицу, что-нибудь вот так:

SELECT * INTO #TempTable FROM SourceTable

Хотя это работает, оно создает блокировки против базы данных tempdb для продолжительность оператора SELECT (довольно долго, если вы траулете через много данных в источнике стол, и еще дольше, если SELECT ... INTO находится в начале длительная явная транзакция) Пока замок стоит, никто другой пользователь может создавать временные таблицы. В фактическое местонахождение узкого места заблокировать системные таблицы tempdb. Позже версии SQL Server, блокировка модель изменилась, и проблема в

К счастью, это была проблема только для SQL 6.5. Это было исправлено в 7.0 и более поздних версиях.

34
ответ дан 28 November 2019 в 06:39
поделиться

Это, вероятно, будет плавать вокруг в течение долгого времени, подпитывая карманы различных «консультантов». Как и во всех мифах, в нем есть зерно правды и много чуши.

Правда: В SQL 2000 и предыдущих версиях были известные проблемы с конфликтом вокруг выделения экстентов в базе данных tempdb. Фактически это утверждение справедливо для всех баз данных, но более заметно в tempdb из-за частого использования tempdb. Это описано в KB328551 :

Когда база данных tempdb сильно загружена используется, SQL Server может испытывать разногласия, когда он пытается выделить страниц.

Из системной таблицы sysprocesses вывод, может появиться ресурс ожидания как «2: 1: 1» (страница PFS) или «2: 1: 3» (SGAM Страница). В зависимости от степени разногласия, это также может привести к SQL Сервер не отвечает на запросы короткие периоды.

Эти операции интенсивно используют tempdb:
Повторное создание и удаление временного таблицы (локальные или глобальные).
Табличные переменные, которые используют tempdb для хранения целей.
Рабочие столы, связанные с КУРСОРЫ.
Рабочие столы, связанные с предложение ORDER BY.
Рабочие таблицы, связанные с предложением GROUP BY.
Рабочие файлы, связанные с HASH PLANS.

Интенсивное и значительное использование этих действия могут привести к раздору

Флаг трассировки -T1118 был добавлен в SQL Server 2000 SP3, который заставлял SQL использовать алгоритм циклического перебора для смешанного распределения страниц. Этот новый алгоритм, если он соотнесен с практикой развертывания базы данных tempdb поверх набора файлов одинакового размера, по одному для каждого процессора, уменьшит конфликт. Флаг трассировки все еще присутствует в SQL 2005/2008, хотя вероятность того, что он понадобится, гораздо меньше.

Все остальное в этом мифе в значительной степени чушь.

  • вызывает ли использование таблиц #temp блокировку? Нет. В худшем случае это увеличивает конкуренцию под нагрузкой в SQL 2000 и более ранних версиях, но это далеко не означает, что он что-либо блокирует. Вам нужно сначала измерить и убедиться, что это так, и если это так, разверните меры по исправлению (выделите один файл tempdb для каждого процессора, сделайте их одинакового размера, включите -T1118).
  • Блокирует ли select ... в #temp что-нибудь на время выбора? Не совсем.
  • Блокирует ли select ... into #temp что-то на время хранимой процедуры, содержащей select? Конечно нет. Просто прочитав это заявление, я расхохотался.

Более подробную информацию можно найти в этой статье: Заблуждения относительно TF1118 .

17
ответ дан 28 November 2019 в 06:39
поделиться

Я бы сказал, что отсутствие защиты от блокировки означает отсутствие блокировки, что является вашим доказательством. Почему метод, в котором создается временная таблица (CREATE или SELECT ... INTO), может иметь значение для блокировки TempDB?

0
ответ дан 28 November 2019 в 06:39
поделиться

Что ж, если бы это было правдой, тогда у mssql были бы проблемы, так как любой большой запрос может использовать tempdb для хранения копии строк. Это часто можно увидеть в планах запросов как буфер таблицы или использовать оператор HASH JOIN, если ему не хватает памяти для его сегментов.

Вы можете посмотреть на использование табличных переменных, который mssql попытается сохранить в памяти и переместить в tempdb, если они вырастут до больших.

DECLARE @foo TABLE (x int, y int, z int)
INSERT INTO @foo(x, y, z) SELECT x, y, z FROM YourTable

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

0
ответ дан 28 November 2019 в 06:39
поделиться

SELECT INTO #temp_table удерживает блокировку схемы в базе данных tempdb на время выполнения оператора, поскольку часть выполняемой им работы - это создание таблицы. Это принципиально отличается от первого создания таблицы с помощью CREATE TABLE # .... и последующего выполнения INSERT на основе набора. SELECT INTO действительно имеет преимущества перед INSERT , в частности, операция минимально регистрируется, если модель восстановления базы данных представляет собой простой или групповой журнал.

0
ответ дан 28 November 2019 в 06:39
поделиться

Почему бы не сделать следующее?

SELECT X, Y, Z
INTO #MyTable
FROM YourTable
WHERE 1 = 2

Оператор запускался бы мгновенно - создавая вашу временную таблицу и избегая любых возможных блокировок. Затем вы можете вставить в него как обычно:

INSERT #MyTable
SELECT X, Y, Z
FROM YourTable
10
ответ дан 28 November 2019 в 06:39
поделиться
Другие вопросы по тегам:

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