Выполнение различных подходов к данным на основе времени - PullRequest
3 голосов
/ 07 декабря 2010

Я спрашиваю об этом в контексте заявления 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 ]

14 голосов
/ 08 декабря 2010

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

  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 на другом, защищенном от бомб, сайте. Сокращение производства за считанные минуты; почти нулевая потеря транзакции.

      • Память / Cache
        Хорошо, у 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 первичных ключей и, таким образом, не наносящим вред мощности реляционного механизма)
    приведет к большему количеству меньших таблиц, уменьшенной базе данных,
    с меньшим количеством индексов,
    требуется меньше соединений

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

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

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

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

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

10 голосов
/ 07 декабря 2010

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

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

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

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

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

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

...