Я извлекаю (только для чтения) информацию из базы данных, имеющей пару тысяч строк в двух разных таблицах, один с 5 столбцами и один с тремя столбцами. Вот мой код:SQL: мой очень короткий код времени; REGR_SLOPE очень медленный
SELECT DISTINCT q1.MACHINE_ID, q1.SIGNAL_ID, ROUND(86400000*(REGR_SLOPE(ts.VALUE, ts.EPOCH) OVER (PARTITION BY ts.MACHINE_SIGNAL_ID))) AS RATE, q1.LAST_VALUE
FROM TSD_SUB ts,
(SELECT ms.MACHINE_SIGNAL_ID, ms.LAST_TIMESTAMP FROM MACHINE_SIGNAL ms
WHERE (ms.MACHINE_ID LIKE 'CV%' OR ms.MACHINE_ID LIKE 'MT%')
AND (ms.SIGNAL_ID = ANY('WFRCOUNT','WFRCNTR') OR ms.SIGNAL_ID LIKE '%WAFERCT%')) q1
WHERE ts.MACHINE_SIGNAL_ID = q1.MACHINE_SIGNAL_ID
AND ts.EPOCH > (q1.LAST_TIMESTAMP - 604800000)
Теперь я не знаю, почему это должно так долго, но мой код работает в течение более чем пятнадцати минут, пока не выйдет время. Внутренний бит,
SELECT * FROM MACHINE_SIGNAL
WHERE (MACHINE_ID LIKE 'CV%' OR MACHINE_ID LIKE 'MT%')
AND (SIGNAL_ID = ANY('WFRCOUNT','WFRCNTR') OR SIGNAL_ID LIKE '%WAFERCT%')
работает очень быстро, потянув пять колонн и около трехсот рядов. Таким образом, полный код использует эту (относительно небольшую) таблицу вместе с большой таблицей с двумя столбцами и несколькими тысячами строк.
Эта база данных является базой данных Oracle, поэтому работа REGR_SLOPE отлично работает. Кроме того, если я просто пытаюсь запустить внешний код немного в то время, он отлично работает:
SELECT DISTINCT ROUND(86400000*(REGR_SLOPE(ts.VALUE, ts.EPOCH) OVER (PARTITION BY ts.MACHINE_SIGNAL_ID))) AS RATE
FROM tsd_sub ts
WHERE ts.machine_signal_id = '366625' -- taken from MACHINE_SIGNAL_ID of the first row of the previous code
AND ts.epoch > (1436855226000 - 604800000) -- from LAST_TIMESTAMP of the first row from the previous code
пробегов менее чем за две секунды и дает мне результат один-клеток. Но я хочу это для каждой записи в моей внутренней таблице, а не только по одной записи за раз. И это не работает вообще.
Я знаю, что это возможно так долго, потому что я занимаю столько записей, но я только прошу, чтобы он сделал две вещи, поэтому я не понимаю, почему это вообще не работает. Это похоже на бесконечный цикл, за исключением того, что я не понимаю, почему он это сделает.
Благодарим вас за внимание и помощь!
EDIT:
Таблица MACHINE_SIGNAL имеет переменную MACHINE_SIGNAL_ID, которая появляется только один раз в MACHINE_SIGNAL, но появляется много раз в TSD_SUB. Поэтому я просто пытаюсь вычислить REGR_SLOPE из нескольких строк в TSD_SUB, чтобы соответствовать одной строке в MACHINE_SIGNAL. Но да, я не могу просто присоединиться к таблицам, потому что TSD_SUB имеет слишком много строк для каждого значения MACHINE_SIGNAL_ID в MACHINE_SIGNAL.
Следующая также занимает слишком много времени, чтобы запустить:
SELECT MACHINE_SIGNAL_ID,
ROUND(86400000*(REGR_SLOPE(ts.VALUE, ts.EPOCH))) AS RATE
FROM TSD_SUB ts,
(SELECT DISTINCT (Max(ts0.EPOCH) - 604800000) AS YESTERDAY
FROM TSD_SUB ts0
WHERE ROWNUM < 100) ts1
WHERE ts.EPOCH > ts1.YESTERDAY
GROUP BY MACHINE_SIGNAL_ID
Это означает, что присоединение его MACHINE_SIGNAL не будет работать вообще, если я не могу также ограничить значениями MACHINE_SIGNAL_ID, которые я смотрю для MACHINE_SIGNAL, но я не могу искать эти значения, не глядя сначала на MACHINE_SIGNAL. Это похоже на проблему catch-22.
Следующий код действительно работает, поэтому HURRAY благодарит всех вас за помощь.
SELECT ms.MACHINE_ID, ms.SIGNAL_ID, ms.MACHINE_SIGNAL_ID, ms.Last_Value, ts.EPOCH, ts.VALUE
FROM MACHINE_SIGNAL ms JOIN
(SELECT ts.MACHINE_SIGNAL_ID, ts.EPOCH, ts.VALUE FROM TSD_SUB ts,
(SELECT (Max(ts0.EPOCH) - 604800000) AS YESTERDAY
FROM TSD_SUB ts0
WHERE ROWNUM < 1000) ts1
WHERE ts.EPOCH > ts1.YESTERDAY) ts
on ts.machine_signal_id = ms.machine_signal_id
WHERE (ms.MACHINE_ID LIKE 'CV%' OR ms.MACHINE_ID LIKE 'MT%') AND
(ms.SIGNAL_ID IN ('WFRCOUNT', 'WFRCNTR') OR SIGNAL_ID LIKE '%WAFERCT%')
Теперь моя задача выяснить, как получить REGR_SLOPE от этой новой таблицы на каждый MACHINE_SIGNAL_ID, а не получать его из всей таблицы. Возможно, это новая проблема, поэтому я вернусь к вам.
Да по какой-то причине, даже если код выше соединения таблиц работает, окружающий бит вычисления REGR_SLOPE еще таймаут. Ниже приведен полный код с частями, которые работают с комментариями.
SELECT myTable.MACHINE_ID,
myTable.SIGNAL_ID,
ROUND(86400000*REGR_SLOPE(myTable.VALUE, myTable.EPOCH)) AS RATE,
myTable.Last_Value
FROM
-- THIS PART WORKS PERFECTLY WELL --
(SELECT ms.MACHINE_ID, ms.SIGNAL_ID, ms.MACHINE_SIGNAL_ID, ms.Last_Value, ts.EPOCH, ts.VALUE
FROM MACHINE_SIGNAL ms JOIN
(SELECT ts.MACHINE_SIGNAL_ID, ts.EPOCH, ts.VALUE FROM TSD_SUB ts,
(SELECT (Max(ts0.EPOCH) - 604800000) AS YESTERDAY
FROM TSD_SUB ts0
WHERE ROWNUM < 1000) ts1
WHERE ts.EPOCH > ts1.YESTERDAY) ts
on ts.machine_signal_id = ms.machine_signal_id
WHERE (ms.MACHINE_ID LIKE 'CV%' OR ms.MACHINE_ID LIKE 'MT%') AND
(ms.SIGNAL_ID IN ('WFRCOUNT', 'WFRCNTR') OR SIGNAL_ID LIKE '%WAFERCT%')) myTable
-- UP TO HERE IS A VALID TABLE WHICH RUNS IN LESS THAN A SECOND --
Group BY myTable.MACHINE_SIGNAL_ID, myTable.MACHINE_ID, myTable.SIGNAL_ID, myTable.Last_Value
Единственное, что вещества, которые здесь добавляются являются REGR_SLOPE и GROUP BY, но даже когда REGR_SLOPE имеет PARTITION внутри него (как у меня было в начале) это еще раз из. Это означает, что функция REGR_SLOPE просто делает что-то, чего я не ожидаю, потому что это происходит очень медленно. Если он проходит через каждую строку, как мне заставить его остановиться, а если нет, то почему это так медленно?
Спасибо!