Выполнение различных подходов к данным на основе времени

Я прошу об этом в контексте заявления PerformanceDBA в этом ответе на другой вопрос, что этот запрос:

SELECT  ProductId,
        Description
    FROM  Product       p,
          ProductStatus ps
    WHERE p.ProductId = ps.ProductId  -- Join
    AND   StatusCode  = 2             -- Request
    AND   DateTime    = (             -- Current Status on the left ...
        SELECT MAX(DateTime)          -- Current Status row for outer Product
            FROM  ProductStatus ps_inner
            WHERE p.ProductId = ps_inner.ProductId
            )

используя таблицу ProductStatus, которая содержит только эффективную (стартовую) дату для состояния, которое изменяется со временем, превзойдет этот запрос:

SELECT  ProductId,
        Description
    FROM  Product       p,
          ProductStatus ps
    WHERE p.ProductId = ps.ProductId  -- Join
    AND   StatusCode  = 2             -- Request
    AND   getdate() BETWEEN DateFrom AND Dateto

используя таблицу ProductStatus, которая содержит как начало, так и дату окончания состояния.

Хотя я принимаю другие утверждения, сделанные для первого подхода, лучше второго, я бы предпочел, чтобы второй подход был быстрее (на основе моего опыта работы с Oracle), потому что он просто фильтрует данные, а не выполнение дополнительного подзапроса и сравнение с ним.

Я хотел бы знать, как Sybase или SQL Server будут обрабатывать эти запросы и что относительная производительность в некоторых простых тестах.

Ответ 1

С одной стороны, хорошо, что вы открыли новый вопрос. Но на руку, извлекая один запрос и спрашивая, работает ли он быстрее, теряет контекст предыдущего вопроса, новый вопрос слишком изолирован. Как я уверен, вы знаете, администрируя базу данных, управляя ресурсами (память/кеш, диск, циклы ЦП), управляющий код (хороший или плохой), который использует эти ресурсы, является частью всего изображения. Производительность - это торговая игра, ничто не бесплатное.

  • Первой проблемой, которую я имел, было дублирование столбца EndDate, которое легко получить. Дублированные столбцы равны обновленным аномалиям. Smirkingman предоставил классический пример: некоторые запросы получат один результат, а другие запросы получат другой. Это просто неприемлемо - крупные организации; или в банках (по крайней мере в развитых странах), где данные проверяются и защищаются. Вы нарушили основное правило нормализации, и есть штрафы, которые нужно заплатить.

    • Обновить аномалии; две версии (уже подробно). Аудиторы не могут передавать систему.

    • Размер таблицы
      В любой большой таблице это проблема, особенно в временных рядах или временных данных, где количество столбцов невелико, а число строк велико. Так что, некоторые скажут, дисковое пространство дешево. Да, так же и ЗППП. Важно то, для чего он используется, и насколько хорошо он позаботится об этом.

      • Дисковое пространство
        Может быть дешево на ПК, но на производственном сервере это не так. В основном вы добавили 62% к размеру строки (13 плюс 8 равно 21) и, следовательно, размер таблицы. В банке, который я назначил в настоящее время, каждый отдел, которому принадлежат данные, оплачивается следующим образом, все хранилище на базе SAN. Цифры рассчитаны на каждый ГБ в месяц (это не высокопоставленный австралийский банк):

        $1,05 для RAID5 Unmirrored (мы знаем, что он медленный, но он дешевый, просто не ставьте на него важную информацию, потому что, если он ломается, после того, как новый диск горячий или холодный, требуется несколько дней для его повторной синхронизации).

        $2.10 для RAID5 Mirrored В SAN, то есть.

        $4.40 для RAID1 + 0
        Минимум для производственных данных, резервных копий журналов транзакций и ночных дампов базы данных.

        $9.80 для RAID1 + 0 реплицированных
        Для идентичного макета SAN на другом, доказательство бомбы, сайт. Сокращение добычи в минутах; почти нулевая потеря транзакций.

      • Память/кэш
        Хорошо, Oracle не имеет этого, но у серьезных банковских dbs есть кеши, и они управляются. Учитывая любой конкретный размер кеша, только 62% строк будут входить в один размер кеша.

      • Логический и физический ввод-вывод
        Это означает, что на 50% больше ввода-вывода для чтения таблицы; как потоковая передача в кеш и диск чтения.

  • Поэтому, независимо от того, выполняется ли запрос лучше или хуже изолированно, это академическая проблема. В контексте вышесказанного таблица работает медленно и на 62% хуже, при каждом доступе. И это влияет на каждого другого пользователя на сервере. Большинство администраторов баз данных не заботятся (я, конечно, не буду), если форма подзапроса будет выполняться на половине скорости, потому что их бонус привязан к принятию аудита, а не только к производительности кода.

    • Кроме того, есть дополнительное преимущество - никогда не пересматривать код и фиксировать транзакции из-за обновления аномалий.

    • И транзакции имеют меньше очков для обновления, поэтому они меньше; меньше блокировочных замков и т.д.

  • Согласовано, что обсуждение в комментариях затруднено. В моем ответе я подробно описал и объяснил два подзапроса. Было недоразумение: вы говорили об этом подзапросе (в предложении WHERE, подзапрос таблицы), и я говорил о другом подзапросе (в списке столбцов скалярный подзапрос), когда я сказал, что он работает так быстро или быстрее. Теперь, когда это было выяснено, я не могу сказать, что первый запрос выше (подзапрос в предложении WHERE, таблица) будет выполняться так же быстро, как второй запрос (с дублированным столбцом); первый должен выполнить 3 сканирования, где второй выполняет только 2 сканирования. (Я осмелюсь сказать, что второй сканирует таблицу.)

    Дело в том, что в дополнение к проблеме изоляции это не справедливое сравнение, я сделал комментарий о скалярных подзапросах. Я бы не стал предлагать, чтобы запрос на 3 сканирования был таким же быстрым или быстрым, как запрос с 2-сканом.

    Утверждение, которое я сделал о подзапросе таблицы 3-скана (который я цитирую здесь), необходимо принять в полном контексте (либо в этой записи, либо выше). Я не отступаю от него.

    Это обычный SQL, подзапрос, использующий мощь механизма SQL, обработка реляционных множеств. Это правильный метод, нет ничего быстрее, и любой другой метод будет медленнее. Любой инструмент отчета будет генерировать этот код несколькими щелчками мыши, без ввода текста.

    Я потратил половину своей жизни на удаление нелегальных альтернатив, таких как дублированные столбцы, которые основаны на проблеме производительности, при этом создатели повторяют мантру, что таблица медленная, поэтому они "денормализированы для производительности". Результат, предсказуемый до начала, представляет собой половину размера таблицы, которая выполняет в два раза быстрее в целом. The Times Series является наиболее распространенным вопросом здесь (ссылка связана с другим вопросом, который связан с другим), но представьте себе проблему в банковской базе данных: ежедневно OpeningExposure и ClosingExposure за Security за Holding за UnitTrust в Portfolio.

  • Но позвольте мне ответить на вопрос, который не был задан. Такое взаимодействие является нормальным, не редкость при работе с внутренними командами разработчиков; он появляется не реже одного раза в месяц. Горячий разработчик аварийной ситуации уже написал и протестировал свой код, используя таблицу с дублированным столбцом, она летит, и теперь она застопорена, потому что я не буду помещать ее в db.

    Нет, я проверю его в контексте всей системы и:

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

    • В другой половине времени производительность [подзапроса таблицы] неприемлема, поэтому я реализую логический (бит) индикатор, чтобы идентифицировать IsCurrent. Это намного лучше, чем дублированный столбец, и обеспечивает скорость с 2 сканированием.

    • Не через миллион лет вы можете заставить меня дублировать колонку; добавив 62% к размеру таблицы; замедление таблицы в полном многопользовательском контексте на 62%; и риск не прошел аудит. И я не сотрудник, у меня нет бонуса.

    Теперь было бы полезно проверить: запрос с дублированным столбцом и запросом с индикатором IsCurrent в полном контексте общего использования ресурсов.

  • Смиркинман поднял хороший момент. И я точно это переформулирую, чтобы он не фрагментировался, а затем на него напал один или другой фрагмент. Не нарушайте это:

    Реляционная база данных,
    Нормализованный опытным реляционным модельером, к истинной Пятой нормальной форме

    (нет обновленных аномалий, без дублированных столбцов),
    с полным соответствием требованиям
    (IDEF1X, особенно в отношении минимизации первичных ключей Id и, следовательно, не разрушает мощность реляционного движка)
    приведет к большему количеству меньших таблиц, меньшей базе данных,
    с меньшим индексом,
    требуется меньшее количество соединений

    (это правильно, больше таблиц, но меньше объединений),
    , и он выйдет из-любого, что нарушит любое из этих правил
    на том же оборудовании, и корпоративная платформа db

    (исключая бесплатное ПО, MS, Oracle, но не позволяйте этому останавливать вас),
    в полном контексте использования OLTP для производства по меньшей мере на один порядок величины,
    и будет намного проще использовать и изменить

    (никогда не нужно "рефакторинг" ).

    Я сделал это как минимум 80 раз. На два порядка не редкость, если я делаю это сам, а не предоставляя рамки для кого-то другого, чтобы сделать это.

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

Ответ 2

Попытка интегрировать производительность в дизайн базы данных всегда приводит к горю позже.

Как обсуждалось в другом потоке, если вы знаете дату, когда статус вступил в силу, вы знаете дату, когда предыдущий статус истек. Хранение ValidFrom и ValidUntil - это ересь; рассмотрите следующий пример, созданный отлаживаемой программой:

Status    ValidFrom   ValidUntil
Open     1 Jan 2010  30 Jan 2010
Closed  20 Jan 2010  30 Mar 2010

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

Создайте свою базу данных правильно, вплоть до любой нормальной формы, которую вы можете переносить.

Протестируйте его с объемами производства в окне производства. Если производительность недостаточна, , а затем, вы получите общую картину того, где настроить.