Запрос Oracle для получения пакетов строк - PullRequest
0 голосов
/ 14 мая 2018

Итак, вот моя проблема: мне нужно получить пакеты строк (операторы select) для миграции в другую базу данных (отличную от oracle).

Предлагаемое решение: я беру партии строк (возможно, используя rowid?) Пример:

batch1: 0-10000, 
batch2: 10000 - 20000,
batchn: 10000(n) - 10000(n+1)

Так каким должен быть мой запрос?

batch1: select * from table_name where rownum >= 0 and rownum < 10000,
batch2: select * from table_name where rownum >= 10000 and rownum < 20000,
batch n: select * from table_name where rownum >= 10000*n and rownum < 10000*(n+1) 

Это не работает, (будет работать только первый выбор).

PS, я извлекаю эти данные из приложения nodejs, и поэтому я отправляю эти пакетные запросы в цикле for.

Ответы [ 3 ]

0 голосов
/ 14 мая 2018

Для иллюстрации моего комментария:

-- Between rows --
SELECT * FROM 
   ( SELECT deptno, ename, sal, ROW_NUMBER() OVER (ORDER BY ename) Row_Num 
       FROM scott.emp
   )
WHERE Row_Num BETWEEN 5 and 10
/

Вы можете заменить оператор между <= и> =, если это необходимо. Вот что я вижу в выводе:

DEPTNO  ENAME   SAL    ROW_NUM
   20   FORD    3000    5
   30   JAMES   950     6
   20   JONES   2975    7
   10   KING    5000    8
   30   MARTIN  1250    9
   10   MILLER  1300    10
0 голосов
/ 15 мая 2018

Если вы хотите сохранить значения rowid, используйте следующий SQL. Для этого SQL потребовалось 4 минуты 20 секунд для работы с таблицей строк с 218 миллионами на двухпроцессорном сервере с выделением 18 ГБ для базы данных.

CREATE TABLE rowids
AS
    WITH
        aset
        AS
            (SELECT ROWID AS row_id, row_number () OVER (ORDER BY ROWID) r
               FROM amiadm.big_table)
    SELECT *
      FROM aset
     WHERE MOD (r, 10000) = 0;

После создания этой таблицы выполните цикл со следующим:

BEGIN
    FOR recs
        IN (  SELECT row_id
                   , LAG (row_id) OVER (ORDER BY row_id) prev_row_id
                   , LEAD (row_id) OVER (ORDER BY row_id) next_row_id
                FROM rowids
            ORDER BY row_id)
    LOOP
        IF prev_row_id IS NULL
        THEN
            SELECT *
              FROM big_table
             WHERE ROWID <= recs.row_id;
        ELSIF next_row_id IS NULL
        THEN
            SELECT *
              FROM big_table
             WHERE ROWID > row_id;
        ELSE
            SELECT *
              FROM big_table
             WHERE ROWID > prev_row_id
               AND ROWID <= row_id;
        END IF;
    END LOOP;
END;
0 голосов
/ 14 мая 2018

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

Если в таблице есть любая комбинация столбцов, которые однозначно идентифицируютrow, лучше сгенерировать ранжирование на основе этого и использовать это ранжирование для идентификации пакетов строк.Например:

SELECT * FROM (
  SELECT table.*, RANK() OVER (ORDER BY column1, column2) as my_rank
  FROM table
  )
WHERE my_rank >= 10000 AND my_rank < 20000

Это будет работать с любым диапазоном и будет воспроизводимым до тех пор, пока значения в используемых столбцах не изменятся и однозначно идентифицируют строку.(На самом деле, я думаю, что это можно было бы использовать, даже если они не однозначно идентифицируют строку, если они работают, чтобы разбить строки на достаточно маленькие партии.)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...