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 не отличается.