как сделать так, чтобы SQL, имеющий много объединений, быстрее для высокой скорости - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть запрос, который занимает довольно много времени для выбора данных.Позвольте мне поделиться моей схемой данных, и есть ли у вас какие-либо идеи о высокой скорости вместо моего SQL?

---------------------------------------------------
time                | statA | statB | statC | ... |
---------------------------------------------------
2018-01-01 00:00:00 |   1   |   2   |   1   | ... | 
---------------------------------------------------
2018-01-01 00:00:01 |   2   |   3   |   5   | ... |
---------------------------------------------------
2018-01-01 00:00:02 |   1   |   4   |   3   | ... |
---------------------------------------------------
...

Что бы я хотел получить, используя запрос, выглядит так:

---------------------------------------
time                |  stat  |  value  |
---------------------------------------
2018-01-01 00:00:00 | statA  |    1    |
---------------------------------------
2018-01-01 00:00:01 | statA  |    2    |
---------------------------------------
2018-01-01 00:00:02 | statA  |    1    |
---------------------------------------
...
...
---------------------------------------
time                |  stat  |  value  |
---------------------------------------
2018-01-01 00:00:00 | statB  |    2    |
---------------------------------------
2018-01-01 00:00:01 | statB  |    3    |
---------------------------------------
2018-01-01 00:00:02 | statB  |    4    |
---------------------------------------
...
...

Итак, мой запрос теперь

(select time, statA as stat, statA as value
from table)
union (
select time, statB as stat, stastB as value
from table)
union (
select time, statC as stat, stastC as value
from table)

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

Любые рекомендации и способы разработки моего SQL?

Ответы [ 3 ]

0 голосов
/ 03 декабря 2018

Вы можете использовать UNPIVOT, как это было предложено @ ibre5041

CREATE TABLE table_ (
  time_ DATE, 
  statA NUMBER, 
  statB NUMBER, 
  statC NUMBER
);

INSERT INTO table_ VALUES (TRUNC(SYSDATE)+ 1/24/60/60*0, 1, 2, 1);
INSERT INTO table_ VALUES (TRUNC(SYSDATE)+ 1/24/60/60*1, 2, 3, 5);
INSERT INTO table_ VALUES (TRUNC(SYSDATE)+ 1/24/60/60*2, 1, 4, 3);

COMMIT;


SELECT TO_CHAR(time_, 'YYYY-MM-DD hh24:mi:ss'), stat, value_
FROM   table_
UNPIVOT (value_ FOR stat IN (statA AS 'statA', statB AS 'statB', statC AS 'statC'))
ORDER BY time_;
0 голосов
/ 03 декабря 2018

unpivot или боковое соединение - лучший метод.Однако ваш метод будет намного быстрее с union all вместо union:

select time, statA as stat, statA as value
from table
union all
select time, statB as stat, stastB as value
from table
union all
select time, statC as stat, stastC as value
from table;

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

0 голосов
/ 03 декабря 2018

Проблемы производительности с UNION иногда могут быть решены с помощью UNION ALL.

Разница в том, что UNION отфильтровывает дубликаты, а UNION ALL - нет (выигрыш в производительности возникает из-за того, что не нужно создавать рабочий стол для фильтрации).дубликаты).

...