По поводу такого количества минусов, я немного удивлен. Неужели всем интересно приходить на собеседование и отвечать на вопросы с листочка? Это конвейер чистой воды… :)
Надеюсь у Вас не сложилось мнение, что я люблю «доминировать» на собеседовании. :) Это далеко не так… Ничего сложного я никогда не спрашивал. Лишь то что нужно для работы. И такие вот моменты что были в этом посте… я их не спрашивал, а рассказывал… потому что с людьми было приятно поделиться опытом. Точно также они и мне рассказывали вещи, которые я не знал.
Теперь по поводу простых вопросов… Многие даже не могут на такой вопрос ответить:
DECLARE @t TABLE (a INT)
INSERT INTO @t (a) VALUES (1), (2), (3), (NULL)
SELECT AVG(a), COUNT(*), COUNT(a)
FROM @t
Одного он вообще повергнул в шок… И мы вместе сидели и разбирались. Почему AVG вернет — 3, а не 1.5 и тд…
При выполнении разница будет только во времени компиляции запроса.
IF OBJECT_ID('dbo.test', 'U') IS NOT NULL
DROP TABLE dbo.test
GO
;WITH E1(N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
)
, E2(N) AS (SELECT 1 FROM E1 a, E1 b)
, E4(N) AS (SELECT 1 FROM E2 a, E2 b)
, E8(N) AS (SELECT 1 FROM E4 a, E4 b)
SELECT val = 1
INTO dbo.test
FROM E8
IF EXISTS(SELECT * FROM dbo.test)
PRINT 1
IF EXISTS(
SELECT *
FROM sys.dm_db_partition_stats
WHERE [object_id] = OBJECT_ID('dbo.test')
AND row_count > 0
AND index_id < 2
) PRINT 1
TRUNCATE TABLE dbo.test
--DELETE TOP(50) PERCENT FROM dbo.test
IF EXISTS(SELECT * FROM dbo.test)
PRINT 1
IF EXISTS(
SELECT *
FROM sys.dm_db_partition_stats
WHERE [object_id] = OBJECT_ID('dbo.test')
AND row_count > 0
AND index_id < 2
) PRINT 1
План будет одинаковый:
Estimated Number of Rows тоже будет идентичным в обоих случаях. А вот количество Actual Number of Rows будет различаться (когда данные есть в таблице и когда их нет, что вполне логично).
Никто не говорил, что нужно гоняться за точностью. Лично я всегда использую sys.partitions вместо COUNT(*) по таблице. Но знать о потенциальных проблемах с некорректными данными в системных представлениях нужно. Или хотя бы иметь представление куда копать в случае проблем подобного рода.
Между прочим и меня часто ловили на всякой ереси :) не всегда же можно все держать в голове на собеседовании. Люди же подсознательно всегда волнуются. А так начал с простого и диалог сам собой начинается.
Хороший вопрос. Если честно, то ответа я не жду. У меня свое видение процесса собеседования. Просто задвавать вопросы быстро наскучивает. Гораздо интереснее начать с простого и понятного вопроса и на основе него построить беседу. Многие из тех кого я побеседовал приходили проверить свой уровень, а не устраиваться на работу. Такие моменты быстро можно уловить и тогда остается просто поговорить о чем-то интересном. Опытом обменяться…
Фраза относилась к оператору Computed Scalar в целом, а не к усечению. Общепризнанные факт, что данный оператор по стоимости на плане практически всегда нулевой или близкий к нему. А по факту может существенно снижать производительность.
Разница между 1 и * была еще во времена SQL Server 2000. Точно могу сказать, что с 2005 планы генерируются одинаково. Если планы одинаковые, то и выполнение будет одинаковым (в рамках погрешности и при условии, что ресурсы сервера ничем другим в это время не нагружены). Единственное что может отличаться, время компиляции.
Спасибо за комментарий. В целом с Вашей точкой зрения согласен.
Однако, нужно отметить — эту возможность я привел для примера. Доступна она только для Enterprise и раз уж ее добавили в эту редакцию, значит от нее иногда есть польза. Когда я нею последний раз пользовался на 2005 сервере, то она отрабатывала быстрее чем создание бекапа, а потом копирование его на шару. Далее никто не запрещает после выполнить RESTORE VERIFYONLY, чтобы проверить корректность созданного бекапа.
Буду очень благодарен, если Вы поделитесь с окружающими скриптами по переносу бекапа на шару.
Теперь по поводу осторожности… Если есть возможность ускорить дисковые операции, то почему не воспользоваться? Вопросы безопасности стоят не во всех организациях. Некоторым подавай максимальную производительность. А бывают ситуации, когда сервер ушел в мир иной и нужно в кратчайшие сроки восстановить базу из бекапа на другом железе. Там применение Instant File Initialization может сократить простой организации и нервы окружающих.
Instant File Initialization я включал для всех серверов, на которых работал и за два года не увидел никаких проблем при ее использовании. Кто столкнулся с проблемами – напишите в комментариях. Буду очень благодарен.
BEGIN TRY
EXEC sys.sp_refreshsqlmodule @name = @obj_name
END TRY
BEGIN CATCH
INSERT INTO #objects (obj_name, err_message, obj_type)
SELECT @obj_name, ERROR_MESSAGE(), @obj_type
END CATCH
на вот такой:
BEGIN TRY
BEGIN TRANSACTION
EXEC sys.sp_refreshsqlmodule @name = @obj_name, @namespace = N'OBJECT'
COMMIT TRANSACTION
END TRY
BEGIN CATCH
INSERT INTO #objects (obj_id, obj_name, err_message, obj_type)
SELECT @obj_id, @obj_name, ERROR_MESSAGE(), @obj_type
IF XACT_STATE() <> 0
ROLLBACK TRANSACTION
END CATCH
Точно знаю, что невалидные объекты есть в Oracle и SQL Server, поскольку на уровне метаданных есть соответствующие признаки. Например, Oracle переводит объекты в состояние INVALID, если зависимый объект изменяется. Если следующая компиляция проходит успешно, то объект становится помечается как VALID.
Теперь по поводу простых вопросов… Многие даже не могут на такой вопрос ответить:
Одного он вообще повергнул в шок… И мы вместе сидели и разбирались. Почему AVG вернет — 3, а не 1.5 и тд…
План будет одинаковый:
Estimated Number of Rows тоже будет идентичным в обоих случаях. А вот количество Actual Number of Rows будет различаться (когда данные есть в таблице и когда их нет, что вполне логично).
в такой конструкции тоже раньше советовали использовать константу. Даже Ицик Бен-Ган об этом в книжке своей писал :)
Разница между 1 и * была еще во времена SQL Server 2000. Точно могу сказать, что с 2005 планы генерируются одинаково. Если планы одинаковые, то и выполнение будет одинаковым (в рамках погрешности и при условии, что ресурсы сервера ничем другим в это время не нагружены). Единственное что может отличаться, время компиляции.
Если сравнить планы, то разница только в * и 1:
Однако, нужно отметить — эту возможность я привел для примера. Доступна она только для Enterprise и раз уж ее добавили в эту редакцию, значит от нее иногда есть польза. Когда я нею последний раз пользовался на 2005 сервере, то она отрабатывала быстрее чем создание бекапа, а потом копирование его на шару. Далее никто не запрещает после выполнить RESTORE VERIFYONLY, чтобы проверить корректность созданного бекапа.
Буду очень благодарен, если Вы поделитесь с окружающими скриптами по переносу бекапа на шару.
Теперь по поводу осторожности… Если есть возможность ускорить дисковые операции, то почему не воспользоваться? Вопросы безопасности стоят не во всех организациях. Некоторым подавай максимальную производительность. А бывают ситуации, когда сервер ушел в мир иной и нужно в кратчайшие сроки восстановить базу из бекапа на другом железе. Там применение Instant File Initialization может сократить простой организации и нервы окружающих.
2008 – только Enterprise и Developer
2008R2 / 2012 / 2014 – редакции Enterprise, Business Intelligence, Standard, Developer
на вот такой: