Ошибка ORA-22813 с сложным запросом SQL - PullRequest
0 голосов
/ 15 января 2009

У меня есть большой оператор SELECT, в котором много вложенных выборок. Когда я запускаю его, он выдает ошибку ORA-22813:

Ora-22813: - Значение Collection из одного из внутренних подзапросов превысило пределы системы и, следовательно, эта ошибка.

Я привел ниже некоторые из вложенных select, которые возвращают огромные данные.

--- 1-й select возвращает наибольшее количество данных.

Могу ли я обрабатывать и обрабатывать огромные данные, возвращаемые INNER SELECT в таблицы, любым альтернативным способом, чтобы не было ошибок памяти меньше, размер сортировки меньше. получить любым другим способом, чтобы запрос успешно обрабатывался без ошибок.

/*****************************************BEGIN

LEFT OUTER JOIN
     (  SELECT *

        FROM STUDENT_COURSE stu_c 

        LEFT OUTER JOIN STUDENT_history ch on stu_c.course_id = ch.ch_course_id 

        LEFT OUTER JOIN STUDENT_master stu_mca on ch.course_history_id = stu_mca.item_id

      ) stu_c ON stu_c.HISTORY_ID = toa.ACTIVITY_ID               ----->This table is joined earlier

LEFT OUTER JOIN

    (SELECT c_e.EV_ID, c_e.EV_NAME, ma.item_id, ma.cata_id
FROM EVENTS c_e LEFT OUTER  
JOIN COURSE_master ma on c_e.event_Id = ma.item_id ) c_e ON c_e.EVENT_ID = toa.ACTIVITY_ID

После этого выбора --- у нас есть GROUP_BY s для дальнейшей сортировки.

--- Я проверил, что если я поставлю дополнительный лимит квалификации как where rownum <30,<20 в каждом из этих SELECT с он работает нормально.


Полный запрос

SELECT * FROM (SELECT 
mcat.CATALOG_ITEM_ID,
mcat.CATALOG_ITEM_NAME ,
mcat.DESCRIPTION,
mcat.CATALOG_ITEM_TYPE,
mcat.DELIVERY_METHOD,
XMLElement("TRAINING_PLAN",XMLAttributes( TP.TPLAN_ID as "id" ),
XMLELEMENT("COMPLETE_QUANTITY", TP.COMPLETE_QUANTITY),
XMLELEMENT("COMPLETE_UNIT", TP.COMPLETE_UNIT),
XMLElement("TOTAL_CREDITS", TP.numberOfCredits ),
XMLELEMENT("IS_CREDIT_BASED", TP.IS_CREDIT_BASED),
XMLELEMENT("IS_FOR_CERT", TP.IS_FOR_CERT),
XMLELEMENT("ACCREDIT_ORG_NAME", TP.ACCRED_ORG_NAME),
XMLELEMENT("ACCREDIT_ORG_ID", TP.accredit_org_id ),
XMLElement("OBJECTIVE_LIST", TP.OBJECTIVE_LIST )
).extract('/').getClobVal() AS PLAN_LIST

FROM 
student_master_catalog mcat 
INNER JOIN
(SELECT stu_tp.TPLAN_ID, 
stu_tp.COMPLETE_QUANTITY, 
stu_tp.COMPLETE_UNIT, 
stu_tp.TPLAN_XML_DATA.extract('//numberOfCredits/text()').getStringVal() as numberOfCredits,
stu_tp.IS_CREDIT_BASED, 
stu_tp.IS_FOR_CERT, 
stu_oa.ACCRED_ORG_NAME, 
stu_tp.TPLAN_XML_DATA.extract('//accreditingOrg/text()').getStringVal() as accredit_org_id,


objective_list.OBJECTIVE_LIST
FROM 
student_training_catalog stu_tp 
LEFT OUTER JOIN
stu_accrediting_org stu_oa on stu_tp.TPLAN_XML_DATA.extract('//accreditingOrg/text()').getStringVal() = stu_oa.ACCRED_ORG_ID
INNER JOIN 
(SELECT * 
FROM 
(SELECT 
stu_tpo.TPLAN_ID AS OBJECTIVE_TPLAN_ID, 
XMLAgg(
XMLElement("OBJECTIVE",
XMLElement("OBJECTIVE_ID",stu_tpo.T_OBJECTIVE_ID ),
XMLElement("OBJECTIVE_NAME",stu_to.T_OBJECTIVE_NAME ),
XMLElement("OBJECTIVE_REQUIRED_CREDITS_OR_ACTIVITIES",stu_tpo.REQUIRED_CREDITS ),
XMLElement("ITEM_ORDER", stu_tpo.ITEM_ORDER ),
XMLElement("ACTIVITY_LIST", activity_list.ACTIVITY_LIST )
)
) as OBJECTIVE_LIST 
FROM 
stu_TP_OBJECTIVE stu_tpo
INNER JOIN 
stu_TRAINING_OBJECTIVE stu_to ON stu_tpo.T_OBJECTIVE_ID = stu_to.T_OBJECTIVE_ID
INNER JOIN 
(SELECT * 
FROM 
(SELECT stu_toa.T_OBJECTIVE_ID AS ACTIVITY_TOBJ_ID, XMLAgg(
XMLElement("ACTIVITY",
XMLElement("ACTIVITY_ID",stu_toa.ACTIVITY_ID ),
XMLElement("CATALOG_ID",COALESCE(stu_c.CATALOG_ID, COALESCE( stu_e.CATALOG_ID, stu_t.CATALOG_ID ) ) ),
XMLElement("CATALOG_ITEM_ID",COALESCE(stu_c.CATALOG_ITEM_ID, COALESCE( stu_e.CATALOG_ITEM_ID, stu_t.CATALOG_ITEM_ID ) ) ),
XMLElement("DELIVERY_METHOD",COALESCE(stu_c.DELIVERY_METHOD, COALESCE( stu_e.DELIVERY_METHOD, stu_t.DELIVERY_METHOD ) ) ),
XMLElement("ACTIVITY_NAME",COALESCE(stu_c.COURSE_NAME, COALESCE( stu_e.EVENT_NAME, stu_t.TEST_NAME ) ) ),
XMLElement("ACTIVITY_TYPE",initcap( stu_toa.ACTIVITY_TYPE ) ),
XMLElement("IS_REQUIRED",stu_toa.IS_REQUIRED ),
XMLElement("IS_PREFERRED",stu_toa.IS_PREFERRED ),
XMLElement("NUMBER_OF_CREDITS",stu_lac.CREDIT_HOURS),
XMLElement("ITEM_ORDER", stu_toa.ITEM_ORDER )
)) as ACTIVITY_LIST 
FROM stu_TRAIN_OBJ_ACTIVITY stu_toa
LEFT OUTER JOIN
(
SELECT distinct lac.LEARNING_ACTIVITY_ID, lac.CREDIT_HOURS


FROM student_training_catalog tp
INNER JOIN stu_TP_OBJECTIVE tpo on tp.TPLAN_ID = tpo.TPLAN_ID
INNER JOIN stu_TRAIN_OBJ_ACTIVITY toa on tpo.T_OBJECTIVE_ID = toa.T_OBJECTIVE_ID
INNER JOIN stu_LEARNINGACTIVITY_CREDITS lac on lac.LEARNING_ACTIVITY_ID = toa.ACTIVITY_ID and tp.TPLAN_XML_DATA.extract ('//accreditingOrg/text()').getStringVal() = lac.ACC_ORG_ID
where tp.tplan_id ='*************'
) stu_lac ON stu_lac.LEARNING_ACTIVITY_ID = stu_toa.ACTIVITY_ID ------>This Select returns correct no. of rows

Я хочу присоединиться к вложенным SELECT s с stu_toa.ACTIVITY_ID. Это решило бы мои проблемы.

Это ниже SELECT внутри LEFT OUTER JOIN есть Проблема. он возвращает слишком много, потому что 3 таблицы объединены напрямую без какого-либо значения квалификации.

LEFT OUTER JOIN
( SELECT ch.COURSE_HISTORY_ID, stu_c.COURSE_NAME, mca.catalog_item_id, mca.catalog_id, mca.delivery_method 
FROM stu_COURSE stu_c 
LEFT OUTER JOIN stu_course_history ch on stu_c.course_id = ch.ch_course_id -
--If I can qualify here with ch.ch_course_id = stu_toa.ACTIVITY_ID (stu_toa.ACTIVITY_ID from the above select with correct no. of rows )
--Here, I get errors because I can't access outside values inside a left outer join

LEFT OUTER JOIN student_master_catalog mca on ch.course_history_id = mca.catalog_item_id
) stu_c ON stu_c.COURSE_HISTORY_ID = stu_toa.ACTIVITY_ID

LEFT OUTER JOIN
(SELECT stu_e.EVENT_ID, stu_e.EVENT_NAME, mca.catalog_item_id, mca.catalog_id, mca.delivery_method FROM stu_EVENTS stu_e LEFT OUTER JOIN student_master_catalog mca on stu_e.event_Id = mca.catalog_item_id ) stu_e ON stu_e.EVENT_ID = stu_toa.ACTIVITY_ID
LEFT OUTER JOIN
(SELECT stu_t.TEST_HISTORY_ID, stu_t.TEST_NAME, mca.catalog_item_id, mca.catalog_id, mca.delivery_method FROM stu_TEST_HISTORY stu_t LEFT OUTER JOIN student_master_catalog mca on stu_t.test_history_id = mca.catalog_item_id) stu_t ON stu_t.test_history_id = stu_toa.ACTIVITY_ID
GROUP BY stu_toa.T_OBJECTIVE_ID) ) activity_list ON activity_list.ACTIVITY_TOBJ_ID = stu_tpo.T_OBJECTIVE_ID 
GROUP BY stu_tpo.TPLAN_ID) ) objective_list ON objective_list.OBJECTIVE_TPLAN_ID = stu_tp.TPLAN_ID
)TP ON TP.TPLAN_ID = mcat.CATALOG_ITEM_ID
WHERE 
mcat.CATALOG_ITEM_ID = '*****************' and mcat.CATALOG_ORG_ID = '********')

Ответы [ 3 ]

2 голосов
/ 17 января 2009

Пожалуйста, опубликуйте DDL, приблизительные размеры (относительно друг друга) и полный запрос, а не просто выдержку.

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

  • Вы уверены, что имеете в виду НАРУЖНОЕ присоединение? Внешнее присоединение студентов к курсам означает, что студенты, которые не посещают какие-либо курсы, все еще будут рядом. Это желаемое поведение?

  • Не select *, если вы хотите ограниченное подмножество столбцов. Перечислите точные столбцы, которые вам нужны. Остальные могут показаться не такими уж построчными, но когда вы умножаете на общее количество строк, такое может означать разницу между сортировками в памяти и разливом на диск.

0 голосов
/ 17 января 2009

Опубликовать DDL ваших таблиц и точный план запроса.

Тем временем попробуйте увеличить pga_aggregate_target, sort_area_size и hash_area_size

0 голосов
/ 15 января 2009

Сколько строк данных вы смотрите? Есть моменты, когда отдельные запросы с программной агрегацией могут работать лучше. Кто-то, обладающий большими знаниями в области оптимизации запросов Oracle, может помочь в этом, а также может помочь настройка параметров ...

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

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