SQL.RU
 client/server technologies
Peoplemind  
 Главная | Документация | Статьи | Книги | Форум | Опросы | Рассылка | Работа | Поиск | FAQ |

Добро пожаловать в форум, Guest  >>  Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик  Ответить
 У меня ошибается СВО !!!   [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
Долго я уже бьюсь с СВО, но так и не получилось вправить ему мозги...
Тут некоторое время назад я уже поднимал подобную тему, но тогда всё уперлось в отсутствие конкретного примера. Сегодня я приведу пример таблицы и того, как работает СВО и как работает RBO. Таблица из примера - сильно уменьшенная и идеализированная модель рабочих таблиц. Но суть от этого не меняется - СВО выбирает неверные планы в обоих случаях, хоть на рабочих таблицах, хоть на тестовой.

И так, поехали...
Вот скрипт на создание тестовой таблицы, на заполнение её данными, на построение индексов и по сбору статистики по этой таблице:
Скрипт на создание таблицы и всякой лабуды к ней

--
--
-- Если в текущей схеме существует таблица
-- TEST_TABLE, то удаляем эту таблицу
--
prompt If exists table TEST_TABLE, then drop it
--
begin
for i in (select 'drop table '||table_name sql_str
from user_tables
where upper(table_name) = 'TEST_TABLE')
loop
if i.sql_str is not null
then execute immediate i.sql_str;
else null;
end if;
end loop;
end;
/
--
--
-- Создаем в текущей схеме таблицу TEST_TABLE
--
prompt Creating table TEST_TABLE in current schema
--
create table test_table
as
select trunc((rownum-1)/4000)+1 num_1,
trunc((rownum-1)/400)+1 num_2,
trunc((rownum-1)/40)+1 num_3,
mod(rownum-1, 10)+1 num_4
from (select 1
from dba_objects
union all
select 1
from dba_objects
union all
select 1
from dba_objects
union all
select 1
from dba_objects
union all
select 1
from dba_objects
union all
select 1
from dba_objects
union all
select 1
from dba_objects
)
where rownum <= 200000
/
--
--
-- Создаем три индекса по таблице TEST_TABLE
--
prompt Create 3 indexes on TEST_TABLE
--
create index test_table_num_1 on test_table (num_1 asc)
/
create index test_table_num_2 on test_table (num_2 asc)
/
create index test_table_num_3 on test_table (num_3 asc)
/
--
--
-- Собираем статистику для таблицы TEST_TABLE и её индексов
--
prompt Compute statistics for TEST_TABLE
analyze table test_table compute statistics for table for all indexes for all indexed columns
/


После того как этот скрипт отработал, делаю в SQLPLUS следующее:
Анализ плана в SQLPLUS при помощи утилиты AUTOTRACE

test@test> set autotrace traceonly
--------------------------------------------------------------------------------
/*
Выполняем несложный запрос к таблице TEST_TABLE в режиме СВО
*/
--------------------------------------------------------------------------------

test@test> select *
2 from test_table
3 where num_1 = 40
4 and num_2 = 391
5 and num_3 = 3901;

40 rows selected.


Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=17)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE' (Cost=2 Card=1 Bytes=17)
2 1 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_1' (NON-UNIQUE) (Cost=9 Card=4000)




Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
26 consistent gets
0 physical reads
0 redo size
1154 bytes sent via SQL*Net to client
521 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
40 rows processed

--------------------------------------------------------------------------------
/*
А теперь тот же самый запрос, но в режиме RBO
*/
--------------------------------------------------------------------------------

test@test> select /*+ rule*/ *
2 from test_table
3 where num_1 = 40
4 and num_2 = 391
5 and num_3 = 3901;

40 rows selected.


Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE'
2 1 AND-EQUAL
3 2 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_1' (NON-UNIQUE)
4 2 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_2' (NON-UNIQUE)
5 2 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_3' (NON-UNIQUE)




Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
21 consistent gets
0 physical reads
0 redo size
1154 bytes sent via SQL*Net to client
521 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
40 rows processed

test@test> spool off



И несложно заметить, что даже на столь простом искусственном примере с небольшим набором данных (всего-то 200 000 записей) СВО строит не самый оптимальный план. В данном примере статистика выполнения запроса отличаеися только параметром consistent gets. На реальных таблицах работа CBO ещё хуже. :-(
Собственно вопрос, куда рыть?
Статистику уже как только не собирал, и при помощи пакета DBMS_STAT, и при помощи оператора ANALYZE - эффекта никакго. Более того, было замечено, что при сборе статистики пакетом DBMS_STAT СВО вообще никогда не использует AND_EQUAL и в любом случае к таблице доступается по одному из индексов. Если же собрать статистику оператором ANALYZE, то СВО использует AND_EQUAL, но эффективность запросов всё-равно хуже, чем в режиме RBO (в этом случае СВО выбирает всего два индекса, в то время как RBO - три. Как следствие - возрастает число physical reads и consistent gets и возрастает время выполнения запроса.)

З.Ы. Сервер ORACLE 9.2.0.4 на Win2K Advanced Server
CPU 4 х 2,8 Pentium XEON with HT
RAM 8 GGb
Дисковая подсистема RAID-10 on 10 x 140GGB HDD

Параметры инициализации :

Содержимое SPFILE

background_dump_dest='c:\oracle\admin\TEST\bdump'
compatible='9.2.0.0.0'
control_files='c:\oradata\test\control01.ctl','d:\oradata\test\control02.ctl','d:\oradata\test\control03.ctl'
core_dump_dest='c:\oracle\admin\test\cdump'
pga_aggregate_target=536870912
workarea_size_policy=AUTO
db_block_size=8192
db_cache_size=1073741824
db_file_multiblock_read_count=16
db_name='TEST'
db_writer_processes=2
dispatchers='(PROTOCOL=TCP) (SERVICE=TESTXDB)'
fast_start_mttr_target=300
hash_join_enabled=TRUE
instance_name='TEST'
java_pool_size=33554432
large_pool_size=67108864
open_cursors=300
optimizer_index_caching=90
optimizer_index_cost_adj=1
parallel_max_servers=16
processes=150
query_rewrite_enabled='FALSE'
remote_login_passwordfile='EXCLUSIVE'
sga_max_size=1476395008
shared_pool_size=268435456
star_transformation_enabled='FALSE'
timed_statistics=TRUE
undo_management='AUTO'
undo_retention=10800
undo_tablespace='UNDOTBS1'
user_dump_dest='c:\oracle\admin\TEST\udump'
28 сен 04, 09:12    [991472] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Вячеслав Любомудров
Member

Откуда: Владивосток
Сообщений: 10431
МОжет быть попробовать собрать системную статистику
автор
...
db_file_multiblock_read_count=16
optimizer_index_caching=90
optimizer_index_cost_adj=1
parallel_max_servers=16
...
Вы же его вынуждаете к определенному поведению - пусть сам попробует разобраться
28 сен 04, 09:36    [991547] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Oracle newbie
Member

Откуда:
Сообщений: 1008
Владимор Конев
Собственно вопрос, куда рыть?
Статистику уже как только не собирал, и при помощи пакета DBMS_STAT, и при помощи оператора ANALYZE - эффекта никакго. Более того, было замечено, что при сборе статистики пакетом DBMS_STAT СВО вообще никогда не использует AND_EQUAL и в любом случае к таблице доступается по одному из индексов. Если же собрать статистику оператором ANALYZE, то СВО использует AND_EQUAL, но эффективность запросов всё-равно хуже, чем в режиме RBO (в этом случае СВО выбирает всего два индекса, в то время как RBO - три. Как следствие - возрастает число physical reads и consistent gets и возрастает время выполнения запроса.)


Почему то не используется куда более селективный индекс TEST_TABLE_NUM_3, а вместо него используется TEST_TABLE_NUM_1 с кардиналити 4000.
Если бы раскручиваться начало с индекса TEST_TABLE_NUM_3 то все было бы хорошо. Можно посмотреть на изминившееся поведение, подставив этот индекс в качестве хинта например.

Почему не подхватывается правильный индекс без хинтов, лично мне трудно сказать, но жутко интересно, поэтому было бы неплохо посмотреть почему оптимизатор выбирает неверный индекс.
сделай плиз в сессии, Перед этим выключив autotrace
SQL>alter session set events='10053 trace name context forever,level 1';
SQL>explain plan for
  2  select * from test_table
  3  where num_1 = 40
  4  and num_2 = 391 
  5  and num_3 = 3901;
и запости сюда трейс полученный. Он будет лежать в user_dump_dest директории.


Regards.
28 сен 04, 10:09    [991692] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
Вячеслав Любомудров
МОжет быть попробовать собрать системную статистику
автор
...
db_file_multiblock_read_count=16
optimizer_index_caching=90
optimizer_index_cost_adj=1
parallel_max_servers=16
...
Вы же его вынуждаете к определенному поведению - пусть сам попробует разобраться


Вот я и спрашиваю, чего я делаю не так,что СВО начинает ошибаться?
Кстати, системная статистика у меня собрана...
Проверка системной статистики

select *
from sys.aux_stats$

SNAME PNAME PVAL1 PVAL2
SYSSTATS_INFO STATUS COMPLETED
SYSSTATS_INFO DSTART 07-27-2004 10:59
SYSSTATS_INFO DSTOP 07-28-2004 09:02
SYSSTATS_INFO FLAGS 1
SYSSTATS_MAIN SREADTIM 4,987
SYSSTATS_MAIN MREADTIM 8,006
SYSSTATS_MAIN CPUSPEED 400
SYSSTATS_MAIN MBRC 27
SYSSTATS_MAIN MAXTHR 92160
SYSSTATS_MAIN SLAVETHR -1
28 сен 04, 10:16    [991733] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
UK0IAI
Member

Откуда: питер
Сообщений: 3084
ИМХО
однако в данном случае самое правильное иметь 1 индекс по трем полям.

Могу предположить что данный случай стратегами оракле чисто игнорирован, ...дескать если вы ребята там у себя кучу индексов на создавали - то мы с этим "париться" вообщето не будем, вот вам хинты - сами рулите...
28 сен 04, 10:18    [991745] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
olek
Member

Откуда: Vologda -> SPb
Сообщений: 1038
SQL> select *
2 from test_table
3 where num_1 = 40
4 and num_2 = 391
5 and num_3 = 3901;

40 rows selected.

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=1 Bytes=17)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE' (Cost=3 Card=1 Bytes=17)

2 1 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_3' (NON-UNIQUE) (Cost=2 Card=40)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
9 consistent gets
0 physical reads
0 redo size
1154 bytes sent via SQL*Net to client
521 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
40 rows processed


SQL> select /*+ rule */ *
2 from test_table
3 where num_1 = 40
4 and num_2 = 391
5 and num_3 = 3901;

40 rows selected.

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE'
2 1 AND-EQUAL
3 2 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_1' (NON-UNIQUE)
4 2 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_2' (NON-UNIQUE)
5 2 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_3' (NON-UNIQUE)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
21 consistent gets
0 physical reads
0 redo size
1154 bytes sent via SQL*Net to client
521 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
40 rows processed
28 сен 04, 10:27    [991787] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
2 Oracle newbie и olek
Попробывал заставить ОРАКЛ использовать индекс test_table_num_3. Как и ожидалось - результат наиболее предпочтительный.
Использование индекса test_table_num_3...

/*
Вот так решает задачу СВО...
*/
test@test> select *
2 from test_table
3 where num_1 = 40
4 and num_2 = 391
5 and num_3 = 3901;

40 rows selected.


Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=17)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE' (Cost=2 Card=1 Bytes=17)
2 1 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_1' (NON-UNIQUE) (Cost=9 Card=4000)




Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
26 consistent gets
0 physical reads
0 redo size
1154 bytes sent via SQL*Net to client
522 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
40 rows processed

/*
А вот что получается, если насильно заставить ОРАКЛ использовать индекс test_table_num_3
*/

test@test> select /*+rule index(test_table test_table_num_3)*/ *
2 from test_table
3 where num_1 = 40
4 and num_2 = 391
5 and num_3 = 3901;

40 rows selected.



Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE (Cost=2 Card=1 Bytes=17)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE' (Cost=2 Card=1 Bytes=17)
2 1 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_3' (NON-UNIQUE) (Cost=2 Card=40)




Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
9 consistent gets
0 physical reads
0 redo size
1154 bytes sent via SQL*Net to client
522 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
40 rows processed

test@test> alter session set events='10053 trace name context forever, level 1';

Session altered.

test@test> explain plan for
2 select *
3 from test_table
4 where num_1 = 40
5 and num_2 = 391
6 and num_3 = 3901;

Explained.


Содержимое трейс-файла:

Результат трассировки сессии по событию 10053

Dump file c:\oracle\admin\test\udump\test_ora_2272.trc
Tue Sep 28 14:26:15 2004
ORACLE V9.2.0.4.0 - Production vsnsta=0
vsnsql=12 vsnxtr=3
Windows 2000 Version 5.0 Service Pack 4, CPU type 586
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Windows 2000 Version 5.0 Service Pack 4, CPU type 586
Instance name: test

Redo thread mounted by this instance: 1

Oracle process number: 37

Windows thread id: 2272, image: ORACLE.EXE


*** 2004-09-28 14:26:15.500
*** SESSION ID:(124.1055) 2004-09-28 14:26:15.421
QUERY
explain plan for
select * from test_table where num_1 = 40 and num_2 = 391 and num_3 = 3901
***************************************
PARAMETERS USED BY THE OPTIMIZER
********************************
OPTIMIZER_FEATURES_ENABLE = 9.2.0
OPTIMIZER_MODE/GOAL = Choose
_OPTIMIZER_PERCENT_PARALLEL = 101
HASH_AREA_SIZE = 4194304
HASH_JOIN_ENABLED = TRUE
HASH_MULTIBLOCK_IO_COUNT = 0
SORT_AREA_SIZE = 2097152
OPTIMIZER_SEARCH_LIMIT = 5
PARTITION_VIEW_ENABLED = FALSE
_ALWAYS_STAR_TRANSFORMATION = FALSE
_B_TREE_BITMAP_PLANS = FALSE
STAR_TRANSFORMATION_ENABLED = FALSE
_COMPLEX_VIEW_MERGING = TRUE
_PUSH_JOIN_PREDICATE = TRUE
PARALLEL_BROADCAST_ENABLED = TRUE
OPTIMIZER_MAX_PERMUTATIONS = 80000
OPTIMIZER_INDEX_CACHING = 90
_SYSTEM_INDEX_CACHING = 0
OPTIMIZER_INDEX_COST_ADJ = 1
OPTIMIZER_DYNAMIC_SAMPLING = 1
_OPTIMIZER_DYN_SMP_BLKS = 32
QUERY_REWRITE_ENABLED = FALSE
QUERY_REWRITE_INTEGRITY = ENFORCED
_INDEX_JOIN_ENABLED = TRUE
_SORT_ELIMINATION_COST_RATIO = 0
_OR_EXPAND_NVL_PREDICATE = TRUE
_NEW_INITIAL_JOIN_ORDERS = TRUE
ALWAYS_ANTI_JOIN = CHOOSE
ALWAYS_SEMI_JOIN = CHOOSE
_OPTIMIZER_MODE_FORCE = TRUE
_OPTIMIZER_UNDO_CHANGES = FALSE
_UNNEST_SUBQUERY = TRUE
_PUSH_JOIN_UNION_VIEW = TRUE
_FAST_FULL_SCAN_ENABLED = TRUE
_OPTIM_ENHANCE_NNULL_DETECTION = TRUE
_ORDERED_NESTED_LOOP = TRUE
_NESTED_LOOP_FUDGE = 100
_NO_OR_EXPANSION = FALSE
_QUERY_COST_REWRITE = TRUE
QUERY_REWRITE_EXPRESSION = TRUE
_IMPROVED_ROW_LENGTH_ENABLED = TRUE
_USE_NOSEGMENT_INDEXES = FALSE
_ENABLE_TYPE_DEP_SELECTIVITY = TRUE
_IMPROVED_OUTERJOIN_CARD = TRUE
_OPTIMIZER_ADJUST_FOR_NULLS = TRUE
_OPTIMIZER_CHOOSE_PERMUTATION = 0
_USE_COLUMN_STATS_FOR_FUNCTION = TRUE
_SUBQUERY_PRUNING_ENABLED = TRUE
_SUBQUERY_PRUNING_REDUCTION_FACTOR = 50
_SUBQUERY_PRUNING_COST_FACTOR = 20
_LIKE_WITH_BIND_AS_EQUALITY = FALSE
_TABLE_SCAN_COST_PLUS_ONE = TRUE
_SORTMERGE_INEQUALITY_JOIN_OFF = FALSE
_DEFAULT_NON_EQUALITY_SEL_CHECK = TRUE
_ONESIDE_COLSTAT_FOR_EQUIJOINS = TRUE
_OPTIMIZER_COST_MODEL = CHOOSE
_GSETS_ALWAYS_USE_TEMPTABLES = FALSE
DB_FILE_MULTIBLOCK_READ_COUNT = 8
_NEW_SORT_COST_ESTIMATE = TRUE
_GS_ANTI_SEMI_JOIN_ALLOWED = TRUE
_CPU_TO_IO = 0
_PRED_MOVE_AROUND = TRUE
***************************************
BASE STATISTICAL INFORMATION
***********************
Table stats Table: TEST_TABLE Alias: TEST_TABLE
TOTAL :: CDN: 179358 NBLKS: 482 AVG_ROW_LEN: 17
-- Index stats
INDEX NAME: TEST_TABLE_NUM_1 COL#: 1
TOTAL :: LVLS: 1 #LB: 350 #DK: 45 LB/K: 7 DB/K: 10 CLUF: 468
INDEX NAME: TEST_TABLE_NUM_2 COL#: 2
TOTAL :: LVLS: 1 #LB: 370 #DK: 449 LB/K: 1 DB/K: 1 CLUF: 468
INDEX NAME: TEST_TABLE_NUM_3 COL#: 3
TOTAL :: LVLS: 1 #LB: 375 #DK: 4484 LB/K: 1 DB/K: 1 CLUF: 468
_OPTIMIZER_PERCENT_PARALLEL = 0
***************************************
SINGLE TABLE ACCESS PATH
Column: NUM_1 Col#: 1 Table: TEST_TABLE Alias: TEST_TABLE
NDV: 45 NULLS: 0 DENS: 2.7877e-006
FREQUENCY HISTOGRAM: #BKT: 179358 #VAL: 45
Column: NUM_2 Col#: 2 Table: TEST_TABLE Alias: TEST_TABLE
NDV: 449 NULLS: 0 DENS: 2.2302e-003
HEIGHT BALANCED HISTOGRAM: #BKT: 75 #VAL: 76
Column: NUM_3 Col#: 3 Table: TEST_TABLE Alias: TEST_TABLE
NDV: 4484 NULLS: 0 DENS: 2.2302e-004
HEIGHT BALANCED HISTOGRAM: #BKT: 75 #VAL: 76
TABLE: TEST_TABLE ORIG CDN: 179358 ROUNDED CDN: 1 CMPTD CDN: 0
Access path: tsc Resc: 53 Resp: 49
Access path: index (equal)
Index: TEST_TABLE_NUM_1
TABLE: TEST_TABLE
RSC_CPU: 1981089 RSC_IO: 19
IX_SEL: 0.0000e+000 TB_SEL: 2.2302e-002
Access path: index (equal)
Index: TEST_TABLE_NUM_2
TABLE: TEST_TABLE
RSC_CPU: 211241 RSC_IO: 3
IX_SEL: 0.0000e+000 TB_SEL: 2.2302e-003
Access path: index (equal)
Index: TEST_TABLE_NUM_3
TABLE: TEST_TABLE
RSC_CPU: 31238 RSC_IO: 2
IX_SEL: 0.0000e+000 TB_SEL: 2.2302e-004
Access path: and-equal
RSC_CPU 109370 RSC_IO: 3
Access path: and-equal
RSC_CPU 971440 RSC_IO: 11
BEST_CST: 2.00 PATH: 4 Degree: 1
***************************************
OPTIMIZER STATISTICS AND COMPUTATIONS
***************************************
GENERAL PLANS
***********************
Join order[1]: TEST_TABLE [TEST_TABLE]
Best so far: TABLE#: 0 CST: 2 CDN: 1 BYTES: 17
Final:
CST: 2 CDN: 1 RSC: 1 RSP: 1 BYTES: 17
IO-RSC: 1 IO-RSP: 1 CPU-RSC: 19811 CPU-RSP: 19811
PLAN
Cost of plan: 2
Operation...........Object name.....Options.........Id...Pid..
SELECT STATEMENT 0
TABLE ACCESS TEST_TABLE BY INDEX ROWID 1
INDEX TEST_TABLE_NUM_1RANGE SCAN 2 1
*** 2004-09-28 14:26:36.562
QUERY
SELECT DECODE('A','A','1','2') FROM DUAL



У кого какие будут предложения???
28 сен 04, 10:52    [991940] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
Мысли вслух: Чего-то не видно и не слышно Ёжика.

З.Ы. 2 OLEK - не поделитись содержимым вашего файла init.ora???
28 сен 04, 10:57    [991957] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
UK0IAI
Member

Откуда: питер
Сообщений: 3084
однако все в порядке у нас :-)

SQL> select /*+CHOOSE */
2 *
3 from test_table
4 where num_1 = 40
5 and num_2 = 391
6 and num_3 = 3901;
40 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: CHOOSE (Cost=2 Card=1 Bytes
=17)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE' (Cost=2 Card
=1 Bytes=17)
2 1 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_3' (NON-UNIQUE) (C
ost=1 Card=1)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
9 consistent gets 0 physical reads
0 redo size
2077 bytes sent via SQL*Net to client
935 bytes received via SQL*Net from client
6 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
40 rows processed

SQL> select /*+rule */
2 *
3 from test_table
4 where num_1 = 40
5 and num_2 = 391
6 and num_3 = 3901;
40 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE'
2 1 AND-EQUAL
3 2 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_1' (NON-UNIQUE)
4 2 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_2' (NON-UNIQUE)
5 2 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_3' (NON-UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
24 consistent gets
0 physical reads
0 redo size
2077 bytes sent via SQL*Net to client
933 bytes received via SQL*Net from client
6 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
40 rows processed
28 сен 04, 11:05    [992016] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
UK0IAI
однако все в порядке у нас :-)

Искренне рад за Вас и , честно говоря, завидую Вам...
Если бы у меня СВО выбирал такой же план , как и у вас, то я был бы счастлив...
Может и вы поделитесь своими параметрами инициализации??? Чувствую, дело именно в том, что какой-то из моих параметров установлен в "неподходящее" значение...
28 сен 04, 11:25    [992155] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
lora_i
Member

Откуда:
Сообщений: 13
Я, честно сказать, не очень сильна в вопросах оптимизации, только учусь, но может поменять параметр optimizer_mode c choose на first_rows или all_ rows, ну и другие параметры инициализации посмотреть ..
28 сен 04, 11:44    [992247] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
olek
Member

Откуда: Vologda -> SPb
Сообщений: 1038
у меня это тестовый серверок и параметры в нем почти сплошь по умолчанию:)
OPTIMIZER_INDEX_CACHING = 50
OPTIMIZER_INDEX_COST_ADJ = 100
DB_FILE_MULTIBLOCK_READ_COUNT = 32

насколько я понял, разница между в выборе планов объясняется в основном значением optimizer_index_cost_adj
28 сен 04, 11:51    [992283] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Я и ёжик
Member

Откуда: СПб
Сообщений: 1469
Владимор Конев
Мысли вслух: Чего-то не видно и не слышно Ёжика.


Мне сейчас некогда плотно вникать в это дело и ставить эксперименты.
Есть предположение, что значением optimizer_index_cost_adj=1 Вы маскируете разницу в стоимости доступа между индексами и берется первый попавшийся из одинаковых :). Поскольку в секции SINGLE TABLE ACCESS PATH,
вроде как, все еще нормально и лучший путь правильный BEST_CST: 2.00 PATH: 4 Degree: 1 ( а четвертым там идет доступ как раз по правильному индексу Access path: index (equal) Index: TEST_TABLE_NUM_3 ).

P.S. Несколько странно выглядит системная статистика
MBRC = 27 при том , что db_file_multiblock_read_count=16.
Вероятно системная статистика собиралась не при текущем занчении
db_file_multiblock_read_count.
А база у Вас производственная или разработческая? Системную статистику имеет смысл собирать на производственной базе , где есть реальная нагрузка, на девелоперской базе такую нагрузку трудно обеспечить, туда лучше экспортировать системную статистику с производственной базы, или вообще её не собирать.
28 сен 04, 11:53    [992294] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
UK0IAI
Member

Откуда: питер
Сообщений: 3084
Владимор Конев
UK0IAI
однако все в порядке у нас :-)

Искренне рад за Вас и , честно говоря, завидую Вам...
Если бы у меня СВО выбирал такой же план , как и у вас, то я был бы счастлив...
Может и вы поделитесь своими параметрами инициализации??? Чувствую, дело именно в том, что какой-то из моих параметров установлен в "неподходящее" значение...


Вот я добился Ваших результатов :-)!!!!!

alter session set optimizer_percent_parallel=100;
alter session set OPTIMIZER_INDEX_CACHING = 90;
alter session set OPTIMIZER_INDEX_COST_ADJ = 1;
select /*+CHOOSE */
*
from test_table
where num_1 = 40
and num_2 = 391
and num_3 = 3901;

SQL> select /*+CHOOSE */
2 *
3 from test_table
4 where num_1 = 40
5 and num_2 = 391
6 and num_3 = 3901;

40 rows selected.

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: CHOOSE (Cost=1 Card=1 Bytes
=17)

1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE' (Cost=1 Card
=1 Bytes=17)

2 1 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_1' (NON-UNIQUE) (C
ost=8 Card=1)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
26 consistent gets 0 physical reads
0 redo size
2077 bytes sent via SQL*Net to client
935 bytes received via SQL*Net from client
6 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
40 rows processed


ВЕРНЕМ ВСЕ НА ДЕФАУЛТ (СБО я не использую по ряду причин, пока)
alter session set optimizer_percent_parallel= 0;
alter session set OPTIMIZER_INDEX_CACHING = 0;
alter session set OPTIMIZER_INDEX_COST_ADJ = 100;

SQL> select /*+CHOOSE */
2 *
3 from test_table
4 where num_1 = 40
5 and num_2 = 391
6 and num_3 = 3901;

40 rows selected.


Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: CHOOSE (Cost=2 Card=1 Bytes
=17)

1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE' (Cost=2 Card
=1 Bytes=17)

2 1 INDEX (RANGE SCAN) OF 'TEST_TABLE_NUM_3' (NON-UNIQUE) (C
ost=1 Card=1)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
9 consistent gets
0 physical reads
0 redo size
2077 bytes sent via SQL*Net to client
935 bytes received via SQL*Net from client
6 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
40 rows processed
28 сен 04, 12:01    [992342] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
Вот ведь чего интересно...
Если параметр optimizer_index_cost_adj выставлять в значение от 1 до 10, то выбор идет по индексу test_table_num_1.
Если выставить значение от 11 до 64 - то по индексу test_table_num_2.
Если ентот параметр сделать >= 65, то используется индекс test_table_num_3.
Однако, если установить optimizer_index_cost_adj > 100, то начинает возникать FULL TABLE SCAN.
Изменение параметров optimizer_index_caching и db_file_multiblock_read_count в любую сторону приводит лишь к изменению стоимости плана. Сам план выполнения не меняется.
30 сен 04, 08:01    [998373] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Я и ёжик
Member

Откуда: СПб
Сообщений: 1469
2 Владимор Конев
Складывается ощущение , что Вы пытаетесь играться параметрами совершенно не вдумываясь, что они означают, по принципу "если посадить миллион обезьян за печатные машинки, то рано или поздно они напечатают Войну и Мир", не очень продуктивный подход. Попытайтесь почитать в документации назначение параметров которые выставляете и способы как они приминяются оптимизатором ( например по статьям товарища Wolfgang Breitling, ссылки тут уже не раз приводились).

Используя системную статистику Вы УЖЕ учитываете разницу в одноблочных и многоблочных операциях, именно их средние значения (SREADTIM и MREADTIM) за период сбора статистики как раз и используются оптимизатором. Поэтому параметр optimizer_index_cost_adj лучше сначала устанавливать в 100 при собранной системной статистике, иначе вы на учтенную системой разницу добавляете еще и свою дополнительную, в виде коэффициента optimizer_index_cost_adj. И только потом аккуратно и осторожно, если Вас что-то не устраивает, можно попытаться уменьшить optimizer_index_cost_adj.

Владимор Конев
Вот ведь чего интересно...
Если параметр optimizer_index_cost_adj выставлять в значение от 1 до 10, то выбор идет по индексу test_table_num_1.
Если выставить значение от 11 до 64 - то по индексу test_table_num_2.
Если ентот параметр сделать >= 65, то используется индекс test_table_num_3.

OPTIMIZER_INDEX_COST_ADJ это корректирующий коэффициент на который умножается стоимость доступа по индексу, полученная оптимизаторм ранее, c дальнейшем округлением.
Соответственно при умножении стоимости доступа на некий коэффициент ( меньше единицы) вы уменьшаете относительную разницу в стоимости между access path, а по результатам округления ( или проста отброса дробной части, точно не знаю) она может вообще совпасть.
Таким образом если разница в стоимости между доступом по индексам TEST_TABLE_NUM_2 и TEST_TABLE_NUM_3 невелика, то умножив их стоимости на коэффициент до 0,64 оптимизатор вероятно получает для этих индексов одинаковые значения и использует из них первый попавшийся, которым и является TEST_TABLE_NUM_2.


Владимор Конев

Однако, если установить optimizer_index_cost_adj > 100, то начинает возникать FULL TABLE SCAN.

Естественно, выставив optimizer_index_cost_adj в значение > 100 вы увеличиваете рассчитанную стоимость доступа по индексу.

Владимор Конев

Изменение параметров optimizer_index_caching и db_file_multiblock_read_count в любую сторону приводит лишь к изменению стоимости плана. Сам план выполнения не меняется.

Странно, по моим наблюдениям эти параметры вообще никак не влияют на оптимизатор при собранной системной статистике.
30 сен 04, 11:31    [999147] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
2 Я и ёжик
Параметр optimizer_index_cost_adj стал уменьшать только потому, что при более высоких (~50 - 70) его значениях в очень многих запросах возникал FTS. Запросы работали очень медленно. Снизив значение до 1 - 10 удалось заставить оптимизатор начать использовать индексы. Скорость работы селектов резко возросла. Но, как выяснилось, СВО выбирает несовсем удачные индексы.
Попробую пересобрать всю статистику, в том числе и системную, выставить все параметры в значение по умолчанию и погляжу, что из этого получится.
30 сен 04, 12:14    [999348] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Я и ёжик
Member

Откуда: СПб
Сообщений: 1469
Владимор Конев
2 Я и ёжик
Параметр optimizer_index_cost_adj стал уменьшать только потому, что при более высоких (~50 - 70) его значениях в очень многих запросах возникал FTS. Запросы работали очень медленно. Снизив значение до 1 - 10 удалось заставить оптимизатор начать использовать индексы. Скорость работы селектов резко возросла. Но, как выяснилось, СВО выбирает несовсем удачные индексы.
Попробую пересобрать всю статистику, в том числе и системную, выставить все параметры в значение по умолчанию и погляжу, что из этого получится.

1) Если запросы которые "работали очень медленно" это запросы из интерактивных пользовотельских приложений, то для них возможно имеет смысл выставить optimizer_mode = first_rows
2) Можно провести несколько итераций сбора системной статистики, собираем один раз, у нас начинают планы запросов уже на основании этой статистики ( но собиралась то она когда работали старые планы), производим сбор статистики еще раз и уже получаем результаты на основании новых планов и.т.д. с постепенным уточнением.
3) Возможно системную статистику надо собирать не за сутки, а за допустим за дневной период и за вечерний период, если нагрузка на систему не равномерна. Допустим днем по сисетеме шарятся операторы выполняющие одиночные запросы к конкретным объектам и тут выгоднее становится индексный доступ, а вечером по системе шляются пакетные задания и отчеты выполняющие кучу сканирований и для них лучше fts. Собрав на такой системе статистику за целые сутки мы получим средние значения которые не будут хороши ни днем ни ночью.
А собрав отдельно "дневную" и "ночную" статистику можно потом job-ом по расписанию загружать нужную в систему. Metalink Note:149560.1
4) Вместо руления optimizer_index_cost_adj, можно попробовать подкорректировать значения статистики SREADTIM в меньшую сторону или MREADTIM в большую (DBMS_STATS.SET_SYSTEM_STATS ), но только без кавалирийских наскоков ;).
30 сен 04, 12:45    [999491] Ответить | Цитировать    Сообщить модератору

 Re: У меня ошибается СВО !!!   [new]
Владимор Конев
Member

Откуда:
Сообщений: 3456
2 Я и ёжик
Принял всё к сведению, постараюсь учесть все рекомендации и применить их на практике
1 окт 04, 05:27    [1000894] Ответить | Цитировать    Сообщить модератору

Все форумы / Oracle Ответить
Rambler's Top100 Powered by ActualForum 1.5.2 Copyright (c) Alex Sibilev 2000-2010