Производительность различных подходов к данным, основанным на времени

Я спрашиваю это в контексте заявления 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 будут обрабатывать эти запросы и какова относительная производительность в некоторых простых тестах.

2 ответа

Решение

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

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

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

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

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

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

        2,10 $ за RAID5 Mirrored
        В SAN это так.

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

        9,80 долл. США за реплицированный RAID1+0
        На идентичный макет SAN на другом, защищенном от бомб, сайте. Сокращение производства за считанные минуты; почти нулевая потеря транзакции.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Реляционная база данных,
    Нормализуется опытным специалистом по реляционным моделям до истинной пятой нормальной формы
    (нет аномалий обновления; нет дублированных столбцов),
    с полным соответствием
    (IDEF1X, особенно в отношении минимизации Id Первичные ключи; и тем самым не наносить вреда реляционному движку)
    приведет к большему, меньшие таблицы, меньшую базу данных,
    с меньшим количеством индексов,
    требуется меньше соединений
    (верно, больше таблиц, но меньше объединений),
    и он превзойдет все, что нарушает любое из этих правил
    на том же оборудовании, и на платформе Enterprise DB
    (исключая бесплатное ПО, MS, Oracle; но не позволяйте этому остановить вас),
    в полном контексте использования OLTP производства
    по крайней мере, на один порядок,
    и это будет намного проще в использовании
    и изменить
    (никогда не нужно "рефакторинг").

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

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

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

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

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

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

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

Проверьте это с объемами производства на коробке спецификации. Если производительность недостаточна, у вас будет общая картина того, где настраивать.

Другие вопросы по тегам