Как оптимизировати запрос?

void_piligrim
Дата: 23.01.2009 09:41:51
 SELECT    
  TK1.DTM AS DTM,
  --DATEADD(minute,TK1.DTM,'19600101') AS DT,
  TK1.DTM-(SELECT MAX(DTM) AS DTM FROM dbo.EURCAD1440 TS1 WHERE TS1.DTM<TK1.DTM) AS DDTM,
 
  SQRT
  (
   SQUARE(TK1.OP/TN1.OP)+
   SQUARE(TK2.OP/TN2.OP)+
   SQUARE(TK3.OP/TN3.OP)+
   SQUARE(TK4.OP/TN4.OP)+
   SQUARE(TK5.OP/TN5.OP)
  )/SQRT(5) AS DXQO,
  SIGN
  (
   SQUARE((TK1.OP-TN1.OP)/TK1.OP)*SIGN((TK1.OP-TN1.OP)/TK1.OP)+
   SQUARE((TK2.OP-TN2.OP)/TK2.OP)*SIGN((TK2.OP-TN2.OP)/TK2.OP)+
   SQUARE((TK3.OP-TN3.OP)/TK3.OP)*SIGN((TK3.OP-TN3.OP)/TK3.OP)+
   SQUARE((TK4.OP-TN4.OP)/TK4.OP)*SIGN((TK4.OP-TN4.OP)/TK4.OP)+
   SQUARE((TK5.OP-TN5.OP)/TK5.OP)*SIGN((TK5.OP-TN5.OP)/TK5.OP)
  )*
  SQRT
  (ABS(
   SQUARE((TK1.OP-TN1.OP)/TK1.OP)*SIGN((TK1.OP-TN1.OP)/TK1.OP)+
   SQUARE((TK2.OP-TN2.OP)/TK2.OP)*SIGN((TK2.OP-TN2.OP)/TK2.OP)+
   SQUARE((TK3.OP-TN3.OP)/TK3.OP)*SIGN((TK3.OP-TN3.OP)/TK3.OP)+
   SQUARE((TK4.OP-TN4.OP)/TK4.OP)*SIGN((TK4.OP-TN4.OP)/TK4.OP)+
   SQUARE((TK5.OP-TN5.OP)/TK5.OP)*SIGN((TK5.OP-TN5.OP)/TK5.OP)
  ))/SQRT(5) AS DSQO,
  (
   TK1.OP/TN1.OP+
   TK2.OP/TN2.OP+
   TK3.OP/TN3.OP+
   TK4.OP/TN4.OP+
   TK5.OP/TN5.OP
  )/5 AS DXMO,
  (
   (TK1.OP-TN1.OP)/TK1.OP+
   (TK2.OP-TN2.OP)/TK2.OP+
   (TK3.OP-TN3.OP)/TK3.OP+
   (TK4.OP-TN4.OP)/TK4.OP+
   (TK5.OP-TN5.OP)/TK5.OP
  )/5 AS DSMO,
  SQRT
  (
   SQUARE(TK1.HI/TN1.HI)+
   SQUARE(TK2.HI/TN2.HI)+
   SQUARE(TK3.HI/TN3.HI)+
   SQUARE(TK4.HI/TN4.HI)+
   SQUARE(TK5.HI/TN5.HI)
  )/SQRT(5) AS DXQH,
  SIGN
  (
   SQUARE((TK1.HI-TN1.HI)/TK1.HI)*SIGN((TK1.HI-TN1.HI)/TK1.HI)+
   SQUARE((TK2.HI-TN2.HI)/TK2.HI)*SIGN((TK2.HI-TN2.HI)/TK2.HI)+
   SQUARE((TK3.HI-TN3.HI)/TK3.HI)*SIGN((TK3.HI-TN3.HI)/TK3.HI)+
   SQUARE((TK4.HI-TN4.HI)/TK4.HI)*SIGN((TK4.HI-TN4.HI)/TK4.HI)+
   SQUARE((TK5.HI-TN5.HI)/TK5.HI)*SIGN((TK5.HI-TN5.HI)/TK5.HI)
  )*
  SQRT
  (ABS(
   SQUARE((TK1.HI-TN1.HI)/TK1.HI)*SIGN((TK1.HI-TN1.HI)/TK1.HI)+
   SQUARE((TK2.HI-TN2.HI)/TK2.HI)*SIGN((TK2.HI-TN2.HI)/TK2.HI)+
   SQUARE((TK3.HI-TN3.HI)/TK3.HI)*SIGN((TK3.HI-TN3.HI)/TK3.HI)+
   SQUARE((TK4.HI-TN4.HI)/TK4.HI)*SIGN((TK4.HI-TN4.HI)/TK4.HI)+
   SQUARE((TK5.HI-TN5.HI)/TK5.HI)*SIGN((TK5.HI-TN5.HI)/TK5.HI)
  ))/SQRT(5) AS DSQH,
  (
   TK1.HI/TN1.HI+
   TK2.HI/TN2.HI+
   TK3.HI/TN3.HI+
   TK4.HI/TN4.HI+
   TK5.HI/TN5.HI
  )/5 AS DXMH,
  (
   (TK1.HI-TN1.HI)/TK1.HI+
   (TK2.HI-TN2.HI)/TK2.HI+
   (TK3.HI-TN3.HI)/TK3.HI+
   (TK4.HI-TN4.HI)/TK4.HI+
   (TK5.HI-TN5.HI)/TK5.HI
  )/5 AS DSMH,
  SQRT
  (
   SQUARE(TK1.LO/TN1.LO)+
   SQUARE(TK2.LO/TN2.LO)+
   SQUARE(TK3.LO/TN3.LO)+
   SQUARE(TK4.LO/TN4.LO)+
   SQUARE(TK5.LO/TN5.LO)
  )/SQRT(5) AS DXQL,
  SIGN
  (
   SQUARE((TK1.LO-TN1.LO)/TK1.LO)*SIGN((TK1.LO-TN1.LO)/TK1.LO)+
   SQUARE((TK2.LO-TN2.LO)/TK2.LO)*SIGN((TK2.LO-TN2.LO)/TK2.LO)+
   SQUARE((TK3.LO-TN3.LO)/TK3.LO)*SIGN((TK3.LO-TN3.LO)/TK3.LO)+
   SQUARE((TK4.LO-TN4.LO)/TK4.LO)*SIGN((TK4.LO-TN4.LO)/TK4.LO)+
   SQUARE((TK5.LO-TN5.LO)/TK5.LO)*SIGN((TK5.LO-TN5.LO)/TK5.LO)
  )*
  SQRT
  (ABS(
   SQUARE((TK1.LO-TN1.LO)/TK1.LO)*SIGN((TK1.LO-TN1.LO)/TK1.LO)+
   SQUARE((TK2.LO-TN2.LO)/TK2.LO)*SIGN((TK2.LO-TN2.LO)/TK2.LO)+
   SQUARE((TK3.LO-TN3.LO)/TK3.LO)*SIGN((TK3.LO-TN3.LO)/TK3.LO)+
   SQUARE((TK4.LO-TN4.LO)/TK4.LO)*SIGN((TK4.LO-TN4.LO)/TK4.LO)+
   SQUARE((TK5.LO-TN5.LO)/TK5.LO)*SIGN((TK5.LO-TN5.LO)/TK5.LO)
  ))/SQRT(5) AS DSQL,
  (
   TK1.LO/TN1.LO+
   TK2.LO/TN2.LO+
   TK3.LO/TN3.LO+
   TK4.LO/TN4.LO+
   TK5.LO/TN5.LO
  )/5 AS DXML,
  (
   (TK1.LO-TN1.LO)/TK1.LO+
   (TK2.LO-TN2.LO)/TK2.LO+
   (TK3.LO-TN3.LO)/TK3.LO+
   (TK4.LO-TN4.LO)/TK4.LO+
   (TK5.LO-TN5.LO)/TK5.LO
  )/5 AS DSML,
  SQRT
  (
   SQUARE(TK1.CL/TN1.CL)+
   SQUARE(TK2.CL/TN2.CL)+
   SQUARE(TK3.CL/TN3.CL)+
   SQUARE(TK4.CL/TN4.CL)+
   SQUARE(TK5.CL/TN5.CL)
  )/SQRT(5) AS DXQC,
  SIGN
  (
   SQUARE((TK1.CL-TN1.CL)/TK1.CL)*SIGN((TK1.CL-TN1.CL)/TK1.CL)+
   SQUARE((TK2.CL-TN2.CL)/TK2.CL)*SIGN((TK2.CL-TN2.CL)/TK2.CL)+
   SQUARE((TK3.CL-TN3.CL)/TK3.CL)*SIGN((TK3.CL-TN3.CL)/TK3.CL)+
   SQUARE((TK4.CL-TN4.CL)/TK4.CL)*SIGN((TK4.CL-TN4.CL)/TK4.CL)+
   SQUARE((TK5.CL-TN5.CL)/TK5.CL)*SIGN((TK5.CL-TN5.CL)/TK5.CL)
  )*
  SQRT
  (ABS(
   SQUARE((TK1.CL-TN1.CL)/TK1.CL)*SIGN((TK1.CL-TN1.CL)/TK1.CL)+
   SQUARE((TK2.CL-TN2.CL)/TK2.CL)*SIGN((TK2.CL-TN2.CL)/TK2.CL)+
   SQUARE((TK3.CL-TN3.CL)/TK3.CL)*SIGN((TK3.CL-TN3.CL)/TK3.CL)+
   SQUARE((TK4.CL-TN4.CL)/TK4.CL)*SIGN((TK4.CL-TN4.CL)/TK4.CL)+
   SQUARE((TK5.CL-TN5.CL)/TK5.CL)*SIGN((TK5.CL-TN5.CL)/TK5.CL)
  ))/SQRT(5) AS DSQC,
  (
   TK1.CL/TN1.CL+
   TK2.CL/TN2.CL+
   TK3.CL/TN3.CL+
   TK4.CL/TN4.CL+
   TK5.CL/TN5.CL
  )/5 AS DXMC,
  (
   (TK1.CL-TN1.CL)/TK1.CL+
   (TK2.CL-TN2.CL)/TK2.CL+
   (TK3.CL-TN3.CL)/TK3.CL+
   (TK4.CL-TN4.CL)/TK4.CL+
   (TK5.CL-TN5.CL)/TK5.CL
  )/5 AS DSMC
  
 FROM 
  dbo.EURCAD1440 TK1 INNER  JOIN
  dbo.EURUSD1440 TK2 ON TK1.DTM = TK2.DTM INNER  JOIN
  dbo.EURJPY1440 TK3 ON TK1.DTM = TK3.DTM INNER  JOIN
  dbo.EURGBP1440 TK4 ON TK1.DTM = TK4.DTM INNER  JOIN
  dbo.EURCHF1440 TK5 ON TK1.DTM = TK5.DTM INNER  JOIN
  
  dbo.EURCAD1440 TN1 ON (SELECT MAX(DTM) AS DTM FROM dbo.EURCAD1440 TS1 WHERE TS1.DTM<TK1.DTM) = TN1.DTM INNER  JOIN
  dbo.EURUSD1440 TN2 ON (SELECT MAX(DTM) AS DTM FROM dbo.EURCAD1440 TS1 WHERE TS1.DTM<TK1.DTM) = TN2.DTM INNER  JOIN
  dbo.EURJPY1440 TN3 ON (SELECT MAX(DTM) AS DTM FROM dbo.EURCAD1440 TS1 WHERE TS1.DTM<TK1.DTM) = TN3.DTM INNER  JOIN
  dbo.EURGBP1440 TN4 ON (SELECT MAX(DTM) AS DTM FROM dbo.EURCAD1440 TS1 WHERE TS1.DTM<TK1.DTM) = TN4.DTM INNER  JOIN
  dbo.EURCHF1440 TN5 ON (SELECT MAX(DTM) AS DTM FROM dbo.EURCAD1440 TS1 WHERE TS1.DTM<TK1.DTM) = TN5.DTM

 ORDER BY TK1.DTM

Можно ли как-то избавится от:
"(SELECT MAX(DTM) AS DTM FROM dbo.EURCAD1440 TS1 WHERE TS1.DTM<TK1.DTM)" в INNER JOIN

Сервер SQL 2000 SP4
alexeyvg
Дата: 23.01.2009 10:17:20
void_piligrim
Можно ли как-то избавится от:
"(SELECT MAX(DTM) AS DTM FROM dbo.EURCAD1440 TS1 WHERE TS1.DTM<TK1.DTM)" в INNER JOIN

Сервер SQL 2000 SP4
Во-первых, нужно посмотреть план запроса и выяснить, вычисляет сервер (SELECT MAX(DTM) AS DTM FROM dbo.EURCAD1440 TS1 WHERE TS1.DTM<TK1.DTM) один раз или шесть.

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

Если шесть, то сделать подзапрос типа:
SELECT
  TK1_DTM AS DTM,
  TK1_DTM-MAX_DTM AS DDTM,
  SQRT
  .....
FROM( SELECT (SELECT MAX(DTM) AS DTM FROM dbo.EURCAD1440 TS1 WHERE TS1.DTM<TK1.DTM) as MAX_DTM,
        TK1.DTM AS TK1_DTM,
        ...
	 FROM 
	  dbo.EURCAD1440 TK1 INNER  JOIN
	  dbo.EURUSD1440 TK2 ON TK1.DTM = TK2.DTM INNER  JOIN
	  dbo.EURJPY1440 TK3 ON TK1.DTM = TK3.DTM INNER  JOIN
	  dbo.EURGBP1440 TK4 ON TK1.DTM = TK4.DTM INNER  JOIN
	  dbo.EURCHF1440 TK5 ON TK1.DTM = TK5.DTM
	 ) as t JOIN
  dbo.EURCAD1440 TN1 ON MAX_DTM = TN1.DTM INNER  JOIN
  dbo.EURUSD1440 TN2 ON MAX_DTM = TN2.DTM INNER  JOIN
  dbo.EURJPY1440 TN3 ON MAX_DTM = TN3.DTM INNER  JOIN
  dbo.EURGBP1440 TN4 ON MAX_DTM = TN4.DTM INNER  JOIN
  dbo.EURCHF1440 TN5 ON MAX_DTM = TN5.DTM
void_piligrim
Дата: 23.01.2009 11:30:55
не знаю, сколько раз вычисляестся но в графе фигурирует 5 раз, переделал на
 SELECT
  ..... 
 FROM 
  (
   SELECT
    (SELECT MAX(DTM) FROM dbo.EURCAD1440 TS1 WHERE TS1.DTM<TZ1.DTM) as MDTM,
    TZ1.DTM AS TDTM
   FROM 
    dbo.EURCAD1440 TZ1
  ) TT1 INNER  JOIN
  dbo.EURCAD1440 TK1 ON TT1.TDTM = TK1.DTM INNER  JOIN
  dbo.EURUSD1440 TK2 ON TT1.TDTM = TK2.DTM INNER  JOIN
  dbo.EURJPY1440 TK3 ON TT1.TDTM = TK3.DTM INNER  JOIN
  dbo.EURGBP1440 TK4 ON TT1.TDTM = TK4.DTM INNER  JOIN
  dbo.EURCHF1440 TK5 ON TT1.TDTM = TK5.DTM INNER  JOIN
  
  dbo.EURCAD1440 TN1 ON TT1.MDTM = TN1.DTM INNER  JOIN
  dbo.EURUSD1440 TN2 ON TT1.MDTM = TN2.DTM INNER  JOIN
  dbo.EURJPY1440 TN3 ON TT1.MDTM = TN3.DTM INNER  JOIN
  dbo.EURGBP1440 TN4 ON TT1.MDTM = TN4.DTM INNER  JOIN
  dbo.EURCHF1440 TN5 ON TT1.MDTM = TN5.DTM
в графе остался только один раз, но время исполнения увеличилось
-старый вариант : Reads 267434, CPU 2266, Duration 4206
-новый вариант : Reads 283418, CPU 2188, Duration 5266

поле DTM первичный ключ во всех таблицах
Senya_L
Дата: 23.01.2009 12:04:22
void_piligrim,

А что за поля такие: TK1, TK2, ... ?
Senya_L
Дата: 23.01.2009 12:05:43
Senya_L
void_piligrim,

А что за поля такие: TK1, TK2, ... ?
Сорри, не поля, конечно же. Что за поле DTM и вообще что делает запрос?
Glory
Дата: 23.01.2009 12:18:02
Это не вариции на тему нарастающего итога ?
void_piligrim
Дата: 23.01.2009 12:25:37
TK1-TK5 - таблицы котировок валютных пар в текущем времени
TN1-TN5 - теже таблицы котировок только должны быть сдвинуты на 1 запись назад по времени

DTM - дата/время во своём формате (количество минут от 1 янвваря 1960 года)

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

вообще шаг времени в таблице обычно одинаковый но инугда попадаются пробелы (выходные), из-за этого весь огород с подзапросами
Glory
Дата: 23.01.2009 12:29:04
Т.е. по 2-м записям сделать вычисление ?
void_piligrim
Дата: 23.01.2009 12:32:08
Да - по двум временным отсчётам.
Но таблиц с данныим 5
Senya_L
Дата: 23.01.2009 12:34:02
void_piligrim,

Странный какой-то запрос. Вы бы привели DDL таблицы и постановку задачи сделали.