powered by simpleCommunicator - 2.0.44     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / SELECT ... FROM /*NESTED TABLE */ TABLE (CAST(..)) vs Перебор по массиву.
1 сообщений из 1, страница 1 из 1
SELECT ... FROM /*NESTED TABLE */ TABLE (CAST(..)) vs Перебор по массиву.
    #32055313
none
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос для тех, кто использует таблицы объектов (Local Collections) на PL/SQL. Чегото не понравилось мне по скорости как все это работает. Простой перебор получается эффективнее. Вот такой базовай пример:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
CREATE OR REPLACE TYPE TFParamObj AS OBJECT
(
PType NUMBER( 1 ),
Param VARCHAR2( 4000 )
);
/

CREATE OR REPLACE TYPE TFParamType AS TABLE OF TFParamObj;
/

DECLARE
	TFParamsArray TFParamType := TFParamType();
	String$ VARCHAR2( 4000 ) := 'Increasingly, programmers are using collection types such as arrays, bags, lists, nested tables, sets, and trees in traditional database applications. To meet the growing demand, PL/SQL provides the datatypes TABLE and VARRAY, which allow you to declare index-by tables, nested tables and variable-size arrays. In this chapter, you learn how those types let you reference and manipulate collections of data as whole objects. You also learn how the datatype RECORD lets you treat related but dissimilar data as a logical unit.';
	StringLength$ NUMBER( 10 ) := LENGTH(String$);
	RNumber1$ NUMBER( 10 );
	RNumber2$ NUMBER( 10 );
	Param1$ NUMBER( 10 );
	MaxLoops$ NUMBER( 10 ) :=  500 ;
BEGIN
	FOR Index1$ IN  1 ..MaxLoops$ LOOP
		TFParamsArray.EXTEND; 
		RNumber1$ := DBMS_RANDOM.VALUE( 1 , StringLength$);
		RNumber2$ := DBMS_RANDOM.VALUE( 1 , StringLength$);
		TFParamsArray(TFParamsArray.COUNT) := TFParamObj(DBMS_RANDOM.VALUE( 1 , 9 ), SUBSTR(String$, RNumber1$, RNumber2$));
	END LOOP;
	 /*
	FOR Index1$ IN 1..9 LOOP 
		SELECT SUM(LENGTH(A.Param)) INTO Param1$ FROM TABLE (CAST(TFParamsArray AS TFParamType)) A WHERE A.PType=Index1$;
		DBMS_OUTPUT.PUT_LINE(Param1$);
	END LOOP;
	*/ 
	DBMS_OUTPUT.PUT_LINE(' --');
 
	 /*
	FOR Index1$ IN 1..9 LOOP
		Param1$ := 0;
		FOR Index2$ IN 1..MaxLoops$ LOOP
			IF TFParamsArray(index2$).PType = Index1$ THEN
				Param1$ := Param1$ + LENGTH(TFParamsArray(Index2$).Param);
			END IF;	
		END LOOP;
		DBMS_OUTPUT.PUT_LINE(Param1$);
	END LOOP;
	*/ 
END;
/


Раскомментируем оба комментария и убеждаемся, что 2 цикла дают одинаковые результаты, то есть алгоритм работает корректно.

Далее меняем струку в блоке DEFINE:
MaxLoops$ NUMBER(10) := 500;
на
MaxLoops$ NUMBER(10) := 20000;

Даем комманду:
Код: plaintext
set timing on;

чтобы смотреть как все это небыстро (быстро) работает.
Раскомментируем первый цикл (и убираем не нужные DBMS_OUTPUT-ы), засекаем время. У меня для первого цикла где используются SELECT-ы по коллекциям выходит ~10 сек.

Далее:
Комментируем первый FOR-LOOP, раскомментируем второй. Время - ~5 сек.

Вывод: фрагмент с SELECTом работает в 2 раза медленнее тупого перебора с помощью циклов. А казалось бы, должно все быть наоборот. Ан нет. Да, первый фрагмент удобнее. Но барал я удобство, мне важна производительность. Либо я чтото не так делаю и тд и тп.

Господа ораклисты, объясните что здесь не так.
Заранее благодарен.

PS: Платформа - Win2000AdvServer+ORACLE8.1.7
...
Рейтинг: 0 / 0
1 сообщений из 1, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / SELECT ... FROM /*NESTED TABLE */ TABLE (CAST(..)) vs Перебор по массиву.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]