Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / SELECT ... FROM /*NESTED TABLE */ TABLE (CAST(..)) vs Перебор по массиву. / 1 сообщений из 1, страница 1 из 1
03.10.2002, 19:05
    #32055313
none
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SELECT ... FROM /*NESTED TABLE */ TABLE (CAST(..)) vs Перебор по массиву.
Вопрос для тех, кто использует таблицы объектов (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
Форумы / Oracle [игнор отключен] [закрыт для гостей] / SELECT ... FROM /*NESTED TABLE */ TABLE (CAST(..)) vs Перебор по массиву. / 1 сообщений из 1, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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