Возможная ошибка с опцией RANGE агрегатов окон и параллельных планов в SQL Server 2012? - PullRequest
2 голосов
/ 02 марта 2012

Я получаю интересное поведение в SQL Server 2012 при использовании опции RANGE с функциями агрегирования окон, и не уверен, является ли это ошибкой или «функцией» SQL Server 2012. У меня есть таблица, определенная следующим образом:

CREATE TABLE [Test].[Trades](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Member] [varchar](20) NOT NULL,
    [TradeDate] [date] NOT NULL,
    [Fund] [varchar](4) NOT NULL,
    [Units] [decimal](28, 8) NOT NULL,
    PRIMARY KEY CLUSTERED 
    (
        [ID] ASC
    )
);

В этой таблице хранятся сделки, совершенные участником в фонде на определенную дату сделки.Участник может совершить> 1 сделку в данном фонде на определенную дату.В дополнение к кластерному индексу у меня есть некластеризованный индекс, определяемый следующим образом:

CREATE NONCLUSTERED INDEX [Ix_TradesIndex] ON [Test].[Trades]
(
    [Member] ASC,
    [Fund] ASC,
    [TradeDate] ASC
)
INCLUDE ([Units]);

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

SELECT T.Member, T.Fund, T.TradeDate, 
SUM(T.Units) OVER(PARTITION BY T.Member, T.Fund
            ORDER BY T.TradeDate
            RANGE BETWEEN UNBOUNDED PRECEDING 
            AND CURRENT ROW) AS TotalShares
FROM Test.Trades AS T;

Это даст мне набор данных, подобный приведенному ниже (пример показывает участника, который совершил> 1 сделку в Fund2на 2005-02-03):

....

Участник 1, Фонд1, 2005-03-31, 0,00

Участник 1, Фонд2, 2005-02-03, 3256.50

Member1, Fund2, 2005-02-03, 3256.50

....

Опция RANGE обеспечила, чтобы предложение было не уникальным (т.е.данный член совершил более одной сделки в данном фонде на определенную дату сделки), в этом окне есть все повторяющиеся строки в верхней части диапазона.Это работает правильно, как и ожидалось.Однако, если я хочу сказать «теперь дайте мне только отдельные строки из этого набора» (т.е. избавьтесь от повторяющихся записей), один из способов задать этот вопрос заключается в следующем:

SELECT DISTINCT T.Member, T.Fund, T.TradeDate, T.TotalShares
FROM
(
    SELECT T.Member, T.Fund, T.TradeDate, 
        SUM(T.Units) OVER(PARTITION BY T.Member, T.Fund
                ORDER BY T.TradeDate
                RANGE BETWEEN UNBOUNDED PRECEDING 
                AND CURRENT ROW) AS TotalShares
    FROM Test.Trades AS T 
) AS T;

Здесь все получаетсяИнтересно, что я вижу, что с большими наборами данных , если план идет параллельно , тогда результирующий набор будет недетерминированным (т. е. запрос дает неправильный ответ, и количество строк, которое возвращает запрос, может изменитьна последующих запусках запроса). Если план не идет параллельно (который я, очевидно, могу принудительно указать, указав OPTION (MAXDOP 1)), тогда запрос всегда возвращает одинаковое количество строк и набор результатов, если «правильный» набор результатов.Для меня это похоже на ошибку в SQL Server 2012.

Мой вопрос: ' У кого-нибудь есть альтернативное объяснение этого поведения, или это ошибка? '

1 Ответ

1 голос
/ 02 марта 2012

Итак, RANGE использует рабочую таблицу на диске для буферизации, а ROWS использует оперативную память (если это возможно).Я попытался бы поменять местами RANGE и поставить ROWS вместо этого, чтобы увидеть:

  1. Семантика все та же (например, вы получаете ожидаемые результаты)
  2. План нене меняются одинаково (например, вы всегда получаете ожидаемые результаты)

Для некоторых запросов это может дать одинаковую семантику, а для других - изменение базовогоЭто значит, поэтому я еще раз подчеркну, что вы должны проверить это изменение.Если семантика одинакова, я почти гарантирую, что производительность улучшится (и ваша вероятность отклонения от плана снизится).

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

Мне было бы интересно рассмотреть это подробнее, вы можете опубликовать сценарий заполнения данных илирезервное копирование где-нибудь (очевидно, без каких-либо частных / частных данных), чтобы инвестировать это ближе?

...