Ok. Вот что я пытаюсь запустить:
USE tempdb;
SELECT TOP 1000000 IDENTITY(INT, 1, 1) Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
CROSS JOIN sys.objects s3
CROSS JOIN sys.objects s4;
Это одна из тех запросов "сделайте меня числами".
Вот проблема. Если я запустил это сразу после запуска службы SQL Server (re), это займет много времени. Не навсегда, как через десять секунд, и я хочу быстрее. Навсегда, как в, я позволил ему пройти два часа один раз случайно и все равно должен был убить его. Я думаю, что он никогда не возвращается. И обычно для моей работы требуется менее двух секунд на моей машине.
Однако, если я это сделаю:
USE tempdb;
SELECT TOP 1000000 IDENTITY(INT, 1, 1) Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
CROSS JOIN sys.objects s3;
DROP TABLE Numbers;
SELECT TOP 1000000 IDENTITY(INT, 1, 1) Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
CROSS JOIN sys.objects s3
CROSS JOIN sys.objects s4;
Затем он работает так, как вы ожидали, - первый SELECT работает менее чем за две секунды, как и второй. Почему бы мне просто не использовать трехстоечную версию? Поскольку в sys.objects не хватает записей для этого числа с кубиками, равным миллиону строк результата. Но это даже не точка.
В любом случае, отсюда, я могу повторить второй DROP/SELECT…INTO столько, сколько захочу, никаких проблем. Каким-то образом эта первая версия с тремя столами сделала это навсегда. По крайней мере, до следующего раза перезагрузка службы и/или перезагрузка компьютера. В этот момент запуск последнего SELECT снова не возвращается. Опять же.
Здесь, где он начинает становиться еще более странным. Если я переняю первую SELECT обратно в двухэтажную версию:
USE tempdb;
SELECT TOP 1000000 IDENTITY(INT, 1, 1) Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2;
DROP TABLE Numbers;
SELECT TOP 1000000 IDENTITY(INT, 1, 1) Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
CROSS JOIN sys.objects s3
CROSS JOIN sys.objects s4;
Это также заставляет второй SELECT работать вечно. Как и одна таблица. Так или иначе, эта трехстоловая версия волшебна!
Что здесь происходит? Почему это медленно?
(И прежде, чем кто-нибудь отметит, что я создаю постоянную таблицу в tempdb, да, я знаю. Изменение на фактические временные таблицы не имеет никакого значения.)
Добавлена информация:
- Это версия для разработчиков SQL Server 2012
- Вывод
EXEC sp_WhoIsActive @find_block_leaders = 1, @sort_order = '[blocked_session_count] DESC'(написанный как XML, поэтому его можно прочитать здесь):
<?xml version="1.0" ?>
<RESULTS1>
<RECORD>
<dd hh:mm:ss.mss>00 00:10:45.066</dd hh:mm:ss.mss>
<session_id>52</session_id>
<sql_text><?query --
SELECT TOP 1000000 IDENTITY(INT, 1, 1) Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
CROSS JOIN sys.objects s3
CROSS JOIN sys.objects s4;
--?></sql_text>
<login_name>my own login name redacted</login_name>
<wait_info>(99ms)LCK_M_X</wait_info>
<CPU> 9,750</CPU>
<tempdb_allocations> 713</tempdb_allocations>
<tempdb_current> 702</tempdb_current>
<blocking_session_id>NULL</blocking_session_id>
<blocked_session_count> 0</blocked_session_count>
<reads> 583,273</reads>
<writes> 537</writes>
<physical_reads> 50</physical_reads>
<used_memory> 3</used_memory>
<status>suspended</status>
<open_tran_count> 2</open_tran_count>
<percent_complete>NULL</percent_complete>
<host_name>my own machine name redacted</host_name>
<database_name>tempdb</database_name>
<program_name>Microsoft SQL Server Management Studio - Query</program_name>
<start_time>2013-11-23 23:48:19.473</start_time>
<login_time>2013-11-23 23:47:47.060</login_time>
<request_id>0</request_id>
<collection_time>2013-11-23 23:59:04.560</collection_time>
</RECORD>
</RESULTS1>
Дополнительная информация:
Почему я помещаю это в tempdb, так это то, что он является частью script, предназначенным для запуска в девственных установках, и там гарантируется tempdb. Как я уже сказал, переход на глобальные таблицы temp не отличается.


