Есть ли способ кэшировать и фильтровать таблицу локально в PL SQL? - PullRequest
0 голосов
/ 10 февраля 2020

Мне приходится обрабатывать таблицу в ORACLE 11g, которая содержит около 5 миллионов записей. Эти записи являются ограничениями скорости вдоль разделенного шоссе. Существует SpeedLimitId, HighwayId и столбец от мили, чтобы обозначить область, к которой применяется ограничение скорости. В настоящее время все записи находятся только на одной стороне разделенного шоссе, и записи должны быть обработаны, чтобы также применить их к другой стороне. Существует таблица уравнений меры, которая позволяет нам узнать, какой диапазон измерения на одной стороне шоссе равен диапазону измерения на другой стороне шоссе. Это позволяет нам вычислить меру того, что событие ограничения скорости будет на другой стороне, вычислив процент от значения меры в диапазоне на измерении, а затем найдя этот же процент от диапазона на противоположной стороне. Запись об ограничении скорости может содержаться в одной записи уравнения измерения или может пересекать несколько из них. Основываясь на информации в таблице ограничения скорости и уравнении измерения, одну или несколько записей необходимо вставить в третью таблицу.

SPEED_LIMIT


+--------------+-----------+--------------+------------+------------+-------+
| SpeedLimitId | HighwayId | FromMilePost | ToMilePost | SpeedLimit | Lane  |
+--------------+-----------+--------------+------------+------------+-------+
|            1 | 75N       |          115 |        123 |         60 | South |
+--------------+-----------+--------------+------------+------------+-------+

MEASURE_EQUATION

+------------+----------------+-----------+---------+-------+----------------+-----------+---------+-------+------------------+
| EquationId | NorthHighwayId | NFromMile | NToMile | NGain | SouthHighwayId | SFromMile | SToMile | SGain | IsHighwayDivided |
+------------+----------------+-----------+---------+-------+----------------+-----------+---------+-------+------------------+
|          1 | 75N            |       105 |     120 |    15 | 75S            |       100 |     110 |    10 | No               |
|          2 | 75N            |       120 |     125 |     5 | 75S            |       110 |     125 |    15 | Yes              |
|          3 | 75N            |       125 |     130 |     5 | 75S            |       125 |     130 |     5 | No               |
+------------+----------------+-----------+---------+-------+----------------+-----------+---------+-------+------------------+

В зависимости от информации в таблицах SPEED_LIMIT и MEASURE_EQUATION будет необходимо вставить хотя бы одну, но в третьей таблице может быть до трех записей. Существует около десятка различных сценариев ios, которые могут иметь место в результате различных значений в полях.
Используя приведенные выше данные, вы можете видеть, что SpeedLimitId 1 отмечен как находящийся на южной стороне шоссе. , но в настоящее время он находится на северной стороне, и что он также охватывает 2 записи уравнения с идентификаторами 1 и 2. В этом случае он охватывает два диапазона измерений, когда одна проезжая часть отделяется и становится разделенной магистралью. Нам нужно разделить исходные записи на два события и добавить их в третью таблицу обработки и вычислить новую меру для полосы, привязанной к югу.

SPEED_LIMIT_PROCESSING

+--------------+-----------+-------+----------+--------+
| SpeedLimitId | HighwayId | LANE  | FromMile | ToMile |
+--------------+-----------+-------+----------+--------+
|            1 | 75N       | North |      115 |    120 |
|            1 | 75S       | South |      110 |    119 |
+--------------+-----------+-------+----------+--------+

Методика расчета меры на южной границе полоса выглядит следующим образом:

+--------------------+----------------------------+-----------------------------+
|                    |  From Measure Translation  |   To Measure Translation    |
+--------------------+----------------------------+-----------------------------+
| Event Measure as % | ((120 – 120)/5) * 100 = 0% | ((123 – 120)/5) * 100 = 60% |
| Offset Measure     | ((15 * 0) / 100 = 0        | ((15 * 60) / 100) = 9       |
| Translated Measure | 110 + 0 = 110              | 110 + 9 = 119               |
+--------------------+----------------------------+-----------------------------+

Моя задача - сделать это максимально эффективным способом. Идея состоит в том, чтобы l oop через каждую запись в таблице SPEED_LIMIT, выбрать соответствующие записи в таблице уравнений меры, а затем на основе информации из этих двух таблиц я бы вставил записи в 3-ю таблицу. Чтобы ограничить переключение контекста PL / SQL, которое я планировал использовать с помощью операторов «BULK COLLECT and FORALL» для запроса таблицы событий и для выполнения операторов вставки, это позволило бы мне делать вещи в пакетном режиме. получить соответствующие записи из таблицы MEASURE_EQUATION, не выполняя запрос sql для каждой записи l oop в таблице SPEED_LIMIT. В MEASURE_EQUATION содержится только около 700 записей, поэтому мне было интересно, есть ли способ, которым я могу кэшируйте его в PL SQL и затем фильтруйте в соответствующие записи для текущей записи SPEED_LIMIT.

Как вы, вероятно, заметили из моего вопроса, я довольно новичок в PL SQL и ORACLE в общем, может быть, я поступаю совершенно неправильно.

...