Этот запрос работает (спасибо тем, кто помог), чтобы получить 30-дневную скользящую среднюю по объему.
SELECT x.symbol, x.dseqkey, AVG(y.VOLUME) moving_average
FROM STOCK_HIST x, STOCK_HIST y
WHERE x.dseqkey>=29 AND x.dseqkey BETWEEN y.dseqkey AND y.dseqkey+29
AND Y.Symbol=X.Symbol
GROUP BY x.symbol, x.dseqkey
ORDER BY x.dseqkey DESC
Однако производительность очень плохая. Я запускаю вышеупомянутое представление (STOCK_HIST), которое объединяет две таблицы (A и B). Таблица A содержит ежедневный объем и дневную дату для более чем 9 000 акций, начиная с 40 лет (более 300 строк в год на каждую из 9 000 акций). Таблица B является таблицей «Ключ даты», которая связывает дату в таблице A с DSEQKEY (int).
Какие у меня варианты улучшения производительности? Я слышал, что взгляды удобны, но не производительны. Должен ли я просто скопировать необходимые столбцы из таблицы A и B в одну таблицу, а затем выполнить приведенный выше запрос? У меня есть индексы в таблицах A и B на биржевом символе + дата (A) и DSEQKEY (B).
Это представление убивает мое выступление? Как я могу улучшить это?
EDIT
По запросу я разместил 2 таблицы и представление ниже. Кроме того, теперь существует один кластерный индекс для представления и каждой таблицы. Я открыт для любых рекомендаций, так как этот запрос, который дает желаемый результат, все еще медленный:
SELECT
x.symbol
, x.dseqkey
, AVG(y.VOLUME) moving_average
FROM STOCK_HIST x
JOIN STOCK_HIST y ON x.dseqkey BETWEEN y.dseqkey AND y.dseqkey+29 AND Y.Symbol=X.Symbol
WHERE x.dseqkey >= 15000
GROUP BY x.symbol, x.dseqkey
ORDER BY x.dseqkey DESC ;
ЗДЕСЬ ВИД:
CREATE VIEW [dbo].[STOCK_HIST]
WITH SCHEMABINDING
AS
SELECT
dbo.DATE_MASTER.date
, dbo.DATE_MASTER.year
, dbo.DATE_MASTER.quarter
, dbo.DATE_MASTER.month
, dbo.DATE_MASTER.week
, dbo.DATE_MASTER.wday
, dbo.DATE_MASTER.day
, dbo.DATE_MASTER.nday
, dbo.DATE_MASTER.wkmax
, dbo.DATE_MASTER.momax
, dbo.DATE_MASTER.qtrmax
, dbo.DATE_MASTER.yrmax
, dbo.DATE_MASTER.dseqkey
, dbo.DATE_MASTER.wseqkey
, dbo.DATE_MASTER.mseqkey
, dbo.DATE_MASTER.qseqkey
, dbo.DATE_MASTER.yseqkey
, dbo.DATE_MASTER.tom
, dbo.QP_HISTORY.Symbol
, dbo.QP_HISTORY.[Open] as propen
, dbo.QP_HISTORY.High as prhigh
, dbo.QP_HISTORY.Low as prlow
, dbo.QP_HISTORY.[Close] as prclose
, dbo.QP_HISTORY.Volume
, dbo.QP_HISTORY.QRS
FROM dbo.DATE_MASTER
INNER JOIN dbo.QP_HISTORY ON dbo.DATE_MASTER.date = dbo.QP_HISTORY.QPDate ;
ЗДЕСЬ ТАБЛИЦА ДАТЫ_MASTER:
CREATE TABLE [dbo].[DATE_MASTER] (
[date] [datetime] NULL
, [year] [int] NULL
, [quarter] [int] NULL
, [month] [int] NULL
, [week] [int] NULL
, [wday] [int] NULL
, [day] [int] NULL
, [nday] nvarchar NULL
, [wkmax] [bit] NOT NULL
, [momax] [bit] NOT NULL
, [qtrmax] [bit] NOT NULL
, [yrmax] [bit] NOT NULL
, [dseqkey] [int] IDENTITY(1,1) NOT NULL
, [wseqkey] [int] NULL
, [mseqkey] [int] NULL
, [qseqkey] [int] NULL
, [yseqkey] [int] NULL
, [tom] [bit] NOT NULL
) ON [PRIMARY] ;
ЗДЕСЬ ТАБЛИЦА QP_HISTORY:
CREATE TABLE [dbo].[QP_HISTORY] (
[Symbol] varchar NULL
, [QPDate] [date] NULL
, [Open] [real] NULL
, [High] [real] NULL
, [Low] [real] NULL
, [Close] [real] NULL
, [Volume] [bigint] NULL
, [QRS] [smallint] NULL
) ON [PRIMARY] ;
ЗДЕСЬ ИНДЕКС (STOCK_HIST)
CREATE UNIQUE CLUSTERED INDEX [ix_STOCK_HIST] ON [dbo].[STOCK_HIST]
(
[Symbol] ASC,
[dseqkey] ASC,
[Volume] ASC
)
ЗДЕСЬ ИНДЕКС QP_HIST
CREATE UNIQUE CLUSTERED INDEX [IX_QP_HISTORY] ON [dbo].[QP_HISTORY]
(
[Symbol] ASC,
[QPDate] ASC,
[Close] ASC,
[Volume] ASC
)
ЗДЕСЬ ИНДЕКС НА DATE_MASTER
CREATE UNIQUE CLUSTERED INDEX [IX_DATE_MASTER] ON [dbo].[DATE_MASTER]
(
[date] ASC,
[dseqkey] ASC,
[wseqkey] ASC,
[mseqkey] ASC
)
У меня нет настроек первичных ключей. Поможет ли это производительность?
EDIT - После внесения предложенных изменений запрос выполняется медленнее, чем раньше. То, что бежало в 10 м 44 с, в настоящее время находится на 30 м и все еще работает.
Я сделал все запрошенные изменения, за исключением того, что я не изменил имя даты в Date_Master и не удалил столбец QPDate из QP_Hist. (У меня есть причины для этого, и я не вижу, как это влияет на производительность, поскольку я не ссылаюсь на это в запросе.)
ПЕРЕСМОТРЕННЫЙ ЗАПРОС
select x.symbol, x.dmdseqkey, avg(y.volume) as moving_average
from dbo.QP_HISTORY as x
join dbo.QP_HISTORY as y on (x.dmdseqkey between y.dmdseqkey and (y.dmdseqkey + 29))
and (y.symbol = x.symbol)
where x.dmdseqkey >= 20000
group by x.symbol, x.dmdseqkey
order by x.dmdseqkey desc ;
PK на QP_History
ALTER TABLE [dbo].[QP_HISTORY]
ADD CONSTRAINT [PK_QP_HISTORY] PRIMARY KEY CLUSTERED ([Symbol] ASC, DMDSeqKey] ASC)
FK на QP_History
ALTER TABLE [dbo].[QP_HISTORY] ADD CONSTRAINT [FK_QP_HISTORY_DATE_MASTER] FOREIGN KEY([DMDSeqKey]) REFERENCES [dbo].[DATE_MASTER] ([dseqkey])
PK на Date_Master
ALTER TABLE [dbo].[DATE_MASTER]
ADD CONSTRAINT [PK_DATE_MASTER] PRIMARY KEY CLUSTERED ([dseqkey] ASC)
РЕДАКТИРОВАТЬ
ЗДЕСЬ ПЛАН ИСПОЛНЕНИЯ