ROW_NUMBER () неправильно упорядочивает записи - PullRequest
2 голосов
/ 04 января 2012

Мне пришлось скопировать данные из таблиц оракула в файлы.

У меня есть запрос на объединение, который выбирает 800 тыс. Записей, поэтому я использовал функцию row_number () вместе с предложением order by, чтобы сгенерировать 4 файла по 200 тыс. Каждый.

Запрос:

SELECT * FROM (
    SELECT  ROW_NUMBER() OVER ( order by FILE_KEY desc ) rn,
        FILE_KEY, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO 
    FROM BANK_INTL_ROUT_TBL rout, BANK_INTL_LOC_TBL loc 
    WHERE loc.CATALOG_NO = rout.FILE_KEY) 
WHERE rn BETWEEN start AND end;

Параметры:

For 1st File  : start =1 ,end = 200000
For 2nd File  : start =200001 ,end = 400000
For 3rd File  : start =400001 ,end = 600000
For 4th File  : start =600001 ,end = 800000

Но когда я проверял последние 10 строк, используя этот запрос в браузере запросов sql, и последние 10 строк файла различаютсяв браузере файлов и запросов SQL последовательность отличается.

SELECT * FROM (
    SELECT  ROW_NUMBER() OVER(  order by FILE_KEY desc ) rn,
        FILE_KEY,ROUTING_NO,INTLROUT_TYPE,ABBR_COUNTRY_CODE_2D,HO_CATALOG_NO 
    FROM BANK_INTL_ROUT_TBL rout, BANK_INTL_LOC_TBL loc 
    WHERE loc.CATALOG_NO=rout.FILE_KEY) 
WHERE rn BETWEEN 709990 AND 80000;

Ответы [ 3 ]

1 голос
/ 04 января 2012

В предложении over упорядочить по уникальному полю в BANK_INTL_LOC_TBL:

SELECT * FROM (
    SELECT  ROW_NUMBER() OVER ( order by loc.**LOC_KEY** desc ) rn,
        FILE_KEY, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO 
    FROM BANK_INTL_ROUT_TBL rout, BANK_INTL_LOC_TBL loc 
    WHERE loc.CATALOG_NO = rout.FILE_KEY) 
WHERE rn BETWEEN start AND end
ORDER BY rn;

ОБНОВЛЕНИЕ : согласно @Shannon Severance comment
добавить порядок по предложению

1 голос
/ 04 января 2012

Это может быть потому, что у вас есть что-то вроде этого

row_number file_key 
799998     same_number
799999     same_number
800000     same_number
800001     same_number
800002     same_number
800003     same_number
800004     same_number

потому что вы заказываете файл file_key.

Как вы заметили, что это разные данные? из ваших других столбцов. Итак, вы можете использовать:

SELECT  ROW_NUMBER() OVER(order by FILE_KEY desc, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO ) rn

Или (вторая причина), ваш базовый стол был изменен между вашими запросами.

UDPDATE : вы можете использовать подсказку use_hash, чтобы ускорить ваш запрос. 5 часов слишком много для этого запроса.

SELECT * FROM (
    SELECT  /*+use_hash(rout loc)*/
        ROW_NUMBER() OVER(order by FILE_KEY desc, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO ) rn,
        FILE_KEY, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO 
    FROM BANK_INTL_ROUT_TBL rout, BANK_INTL_LOC_TBL loc 
    WHERE loc.CATALOG_NO = rout.FILE_KEY) 
WHERE rn BETWEEN start AND end;
0 голосов
/ 04 января 2012

Если у вас есть запасной диск в вашей установке Oracle (что вам следует!), То вместо выполнения внутреннего запроса 4 раза может произойти следующее:

CREATE TABLE bank_data
NOLOGGING
PARALLEL 4
AS SELECT  ROW_NUMBER() OVER ( order by FILE_KEY desc ) rn,
    FILE_KEY, ROUTING_NO, INTLROUT_TYPE, ABBR_COUNTRY_CODE_2D, HO_CATALOG_NO 
FROM BANK_INTL_ROUT_TBL rout, BANK_INTL_LOC_TBL loc 
WHERE loc.CATALOG_NO = rout.FILE_KEY);

Степень параллелизма (число 4 в моем примере здесь) будет зависеть от того, сколько параллельной работы может выполнять ваша база данных, в основном зависит от количества процессоров.

После того, как это закончится (что должно занять заметно меньше 5 часов!), Вы можете запустить простые операции выбора в таблице bank_dump, чтобы получить нужные вам записи

SELECT *
FROM bank_dump
where rn < 200000

для вашего первого набора данных, например.

...