SQL Server DBA
  • IT Assistant — новый сервис для ИТ специалистов

    Везде знакомые люди :)

    Если, по существу, то идея хорошая и к написанию текстовки подошла ответственно. От себя могу лишь пожелать удачи в развитии сервиса и посоветовать подготовить еще одну статью, но уже технического характера. Мне было бы интересно почитать какие технологии выбрали, на чем база крутится и тд. На том же Хабре или ДОУ опубликовать и явно будет профит.

  • Fail review: неудачные собеседования vol.2

    Некоторые вещи увы не вошли в первоначальное повествование, но думаю для продолжения рубрики наберется :)

    Следующее по очереди, что запомнилось из треша прошлых лет — это собеседование на должность QA девочки «боцман-модель-тамада» с пониженной моральной ответственностью или NET девелопера с комплексом «трехлитровки». Эти собесы я не проводил, но воочию наблюдал.

  • DOU Books: 5 классических книг от Сергея Сыроватченко, SQL Server DBA

    Спасибо. Рад что Вам понравилось. Скоро будет новый пост, но уже в ином формате :)

    Силами редакции DOU планируется выпуск свежей подборки про трешовые собеседования. Там как раз будет моя любимая зашкварная история из жизни про «зеков, детский садик и стулья».

  • DOU Books: 5 классических книг от Сергея Сыроватченко, SQL Server DBA

    Еще думаю уместно поделиться ссылкой на целую подрорку бесплатных книг по SQL Server от RedGate. Крайне советую: SQL Server Execution Plans, Inside the SQL Server Query Optimizer и SQL Server Transaction Log Management. Хотя там вся литература весьма кошерная :)

  • Техническое собеседование: 10 каверзных вопросов по SQL

    Раз я тоже ответа не дождался. Что ж тогда я скажу.

    COLLATE на уровне базы влияет на то как будут интерпретироваться имена объектов на этапе построения плана выполнения (binding). То есть если у нас имя таблицы написано строчными, а в метаданных хранится заглавными и на базе регистрозависимый коллейшен, то будет ошибка. И это распространяется на все пользовательские объекты.

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

  • Техническое собеседование: 10 каверзных вопросов по SQL

    От COLLATE на какой базе? Истина как известно кроется в деталях :)

  • Техническое собеседование: 10 каверзных вопросов по SQL

    А вот это уже грубовато. То и так понятно, что могут быть ошибки при длинном строковом литерале который является индексным полем. Какой вопрос такой и ответ.

    Хочется ответочку то давайте :) вариант такой:

    DECLARE @a INT
    SELECT @A

    всегда будет работать? И от каких настроек зависит.

  • Техническое собеседование: 10 каверзных вопросов по SQL

    Претензий не было. Думал будет более хардкорно :) хотя как для пятницы отлично все. Спасибо.

  • Техническое собеседование: 10 каверзных вопросов по SQL

    1) Спорить не буду. Не написал, хотя штука такая есть (за все время ни разу к слову не включали).

    2) Откатить можно:

    SELECT a = 1
    INTO #t
    
    BEGIN TRAN
    TRUNCATE TABLE #t
    ROLLBACK
    
    SELECT * FROM #t

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

    В плане различий BOL можно почитать. Тем более выше народ тоже комментарии оставлял.

    3) Если по такому полю нужно фильтровать, то почему не FTS? Если не вариант то сделать вычисляемое поле и усечь его чтобы все влезало в любимые 900 байт (начиная с 2016го увеличили до 1700 байт).

    SELECT a = CAST(NULL AS VARCHAR(MAX))
    INTO #t
    
    ALTER TABLE #t ADD b AS CAST(a AS VARCHAR(8000))
    
    CREATE NONCLUSTERED INDEX ix ON #t (b)

    4) Хотите сказать что UNION всегда будет приводить к сортировке?

    DECLARE @a TABLE (a INT PRIMARY KEY)
    DECLARE @b TABLE (b INT PRIMARY KEY)
    
    SELECT *, b = 1 FROM @a
    UNION
    SELECT *, b = 2 FROM @b

    тут оптимизатор вообще решил конкатенацию входящих потоков делать.

    В плане «параллельности» речь не о паралелльных планах и не о настройках. А о том как эти операторы работают когда идет row goal через TOP(N). Вычитываются ли данные последующим оператором если текущий вернул нужное число строк:

    SELECT TOP(1) AddressID
    FROM (
        SELECT TOP(1) AddressID
        FROM Person.[Address]
        WHERE AddressLine1 = @AddressLine
    
        UNION ALL
    
        SELECT TOP(1) AddressID
        FROM Person.[Address]
        WHERE AddressLine2 = @AddressLine
    ) t

    т.е. если первый запрос вернет строку, второй физически данные не вычитает в отличии от UNION.

    К слову мне Ваши замечания понравились :) Спасибо.

  • Техническое собеседование: 10 каверзных вопросов по SQL

    Пожалуйста пните в каких местах и что неверно. Разумную критику всегда воспринимаю на ура. А вот пустословие штука опасная :)

    Если в плане того, что разметка поехала вначале первого коммента, то там да можно придраться в сути отдельных предложений. Кроме того можно поставить под сомнение трактование поведения отключенного ANSI_NULLS (что мало кто делает):

    SET ANSI_NULLS OFF
    SELECT 1
    WHERE 1 != NULL

    А так меня уже прямо заинтриговало )))

  • Техническое собеседование: 10 каверзных вопросов по SQL

    Хотя в том же MS SQL можно ее включить.

    Плиз ткните в BOL. Интересно для себя.

  • Техническое собеседование: 10 каверзных вопросов по SQL

    Код и вправду забавный, но пишет народ крайне разные. Есть и откровенная индусня. Есть и толковые ребята, которые так пишут. Когда-то ревьювал код написанный MVP, то вот такое встречалось в цикле:

    DECLARE @a INT = 1
          , @b INT
    
    SELECT @a = 2
         , @b = @a

    то есть код работает исходя из предположения о порядке присваивания переменных на каждой итерации.

    Либо вариант с использованием меток:

    lbl:
    
    DELETE TOP(1000) FROM ...
    WHERE ...
    
    IF @@rowcount > 0
        GOTO lbl

    вместо использования цикла или курсора. Как говориться на вкус и цвет фломастеры разные.

  • Техническое собеседование: 10 каверзных вопросов по SQL

    Ну я бы так не сказал. Есть ситуации где данные нюансы имеют смысл и часто в коде могут встречаться. Например вот такой пример:

    DECLARE @a INT = 1
          , @b INT = 1
    
    SELECT @a = 2
    WHERE 1=0
    
    SET @b = (SELECT 2 WHERE 1=0)
    
    SELECT @a, @b

    Другое дело... стоит ли такое спрашивать на собесах уровня jun / mid. Я лично не спрашивал.

  • Техническое собеседование: 10 каверзных вопросов по SQL

    По правде тут с Вами согласен. Хоть и чуть включил критику, но то что мало техстатей это верно подмечено. Приятно порадовало в пятницу :)

  • Техническое собеседование: 10 каверзных вопросов по SQL

    разница между UNION и UNION ALL

    Разница в том, что данные операторы на физическом уровне работают по разному. UNION ALL последовательный, а UNION — параллельно выполняется. Пример тут.

    В плане каверзных вопросов можно вспомнить немного синтаксического идиотизма. Скажем чем отличается векторная агрегация от скалярной:

    SELECT COUNT(1)
    WHERE 1=0
    
    SELECT COUNT(1)
    WHERE 1=0
    GROUP BY ()

    Или почему тут такой результат:

    SELECT N'уйти в туман как ежику'
    WHERE 'reason' = 'no'
    HAVING COUNT(*) = 0

    Или такой:

    SELECT MAX(N'вроде и смешно а причины нет как и результата')
    WHERE 1=0
    Підтримали: anonymous, Boris Potapuff
  • Техническое собеседование: 10 каверзных вопросов по SQL

    Относительно П6 тоже много интересного. Во первых, TRUNCATE и DELETE пишутся в лог. Но разница лишь в том, что первая минимально протоколируется, а вторая полностью. Потому и наблюдается различия в скорости выполнения этих команд. Плюс еще и в том, что TRUNCATE можно откатить, а значит эта команда поддерживает транзакции.

    Тут можно вспомнить особенность табличный переменных, которые как раз и не поддерживают пользовательские транзакции:

    DECLARE @a TABLE (a INT)
    
    BEGIN TRAN
    INSERT INTO @a VALUES (1)
    ROLLBACK
    
    SELECT * FROM @a
    Для типа CHAR используется статическое распределение памяти, из-за чего операции с ним быстрее, чем с VARCHAR

    Смотря как проверять и что делать. Зачастую CHAR менее производительный (не забываем что пробелы добавляются автоматом), чем VARCHAR (точно также как и VARCHAR быстрее NVARCHAR)

    DECLARE @a CHAR(8000) = '1'
          , @b VARCHAR(8000) = '1'
    
    DECLARE @s DATETIME = GETDATE()
    
    WHILE LEN(@a) != 8000 BEGIN
        SET @a = '1' + @a
    END
    
    SELECT DATEDIFF(MICROSECOND, @s, GETDATE()) / 1000.
    
    SET @s = GETDATE()
    
    WHILE LEN(@b) != 8000 BEGIN
        SET @b = '1' + @b
    END
    
    SELECT DATEDIFF(MICROSECOND, @s, GETDATE()) / 1000.
  • Техническое собеседование: 10 каверзных вопросов по SQL

    Вначале статьи стоило бы указать для какой DBMS были приведены примеры. Поскольку далее большинство примеров идет с учетом специфики SQL Server буду придираться строго в разрезе этой DBMS.

    2 <> NULL вернет UNKNOWN, а не FALSE. Поскольку SQL Server оперирует троичной логикой при сравнении операторов.

    Если же этот запрос будет выполняться MS SQL Server, то по умолчанию будет сгенерирована ошибка. Впрочем, это поведение настраивается.

    Что-то я такой настройки в SQL Server не встречал. По правде не знаю, как в MySQL, но в SQL Server такой запрос работать не будет:

    SELECT a, b
    FROM (
        SELECT a = 1, b = 1
    ) t
    GROUP BY a
    

    Column ’t.b’ is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

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

    Суть порядка столбцов в оптимальном использовании predicate pushdown на этапе физического чтения из индекса. То есть не вычитывать весь индекс, а потом по нему фильтровать, а выгребать только то что нужно (именно потому SQL Server и старается пропихивать предикаты до операций соединения):

    IF OBJECT_ID('tempdb.dbo.#t') IS NOT NULL
        DROP TABLE #t
    GO
    
    SELECT TOP(1000) a = 0, b = 'A'
    INTO #t
    FROM [master].dbo.spt_values
    
    INSERT INTO #t VALUES (1, 'B')
    GO
    
    CREATE NONCLUSTERED INDEX ix1 ON #t (a, b)
    GO
    
    SELECT COUNT(1)
    FROM #t
    WHERE b = 'B'
        AND a = 1
    
    SELECT COUNT(1)
    FROM #t
    WHERE b = 'B'
    
    Table '#t'. Scan count 1, logical reads 2, ....
     SQL Server Execution Times:
       CPU time = 0 ms,  elapsed time = 0 ms.
    
    Table '#t'. Scan count 1, logical reads 5, ....
     SQL Server Execution Times:
       CPU time = 0 ms,  elapsed time = 1 ms.
    

    Execution plan

  • .NET розробники Харкова — періодичні зустрічі в пабах

    По правде, мне идея автора топика весьма понравилась. Давно была мысль собрать народ по базам данных. Но, в данном случае, охват аудитории может намного выше быть.

  • MeetUp “SQL Server: XML vs JSON”

    Сейчас по факту зарегистрировалось 74 человека. Исходя из предыдущего опыта, обычно приходит от 60-70%. Так что если есть желание прийти послушать вживую — места найдем всегда :)

  • SQL Server 2016/2017: особенности работы с JSON

    Есть Primary/Secondary XML индексы, есть Selective (аналог фильтрованных индексов, начиная с 2012 SP1), но конкретно на переменную индекс не навесить.

← Сtrl 12345 Ctrl →