Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой? / 21 сообщений из 21, страница 1 из 1
14.07.2017, 09:06
    #39488830
Pavel_PV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Всем доброго.
Разбираясь с одной проблемой наткнулся на другую, так сказать даже не ожидал и понять не могу что делаю не так. Суть - есть партицированная табличка. По дате партиционирования создан BITMAP index. При извлечении всех данных из двух партиций оракл предлагает использовать созданный bitmap index, но не full scan. Предлагает обоснованно, cost в случае с Bitmap действительно ниже. Но конечно глупость фуллсканить данные используя одноблочное чтение. При этом количество строк оценивается корректно. Стоит 12.1.0.2. Понятно, что при фуллскане время отработки меньше.
Интересно что делаю не так?
Тест кейс:
Код: plsql
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.
CREATE TABLE T1
(
  D1  DATE,
  N number
)
PARTITION BY RANGE (D1)
INTERVAL(NUMTODSINTERVAL(1, 'DAY'))
( PARTITION P_2010   VALUES LESS THAN (TO_DATE('2017-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')));

declare
 vDate date;
BEGIN
  FOR i IN 1..100000
  LOOP
     vDate:= date '2017-07-14';
     insert into T1(D1,N) select vDate, i from dual;
  END LOOP;
  commit;
  --
  FOR i IN 1..100
  LOOP
     vDate:= vDate + i;
     insert/*+ ENABLE_PARALLEL_DML PARALLEL(8)*/ into T1(D1,N) select vDate, N from T1 where T1.D1 = date '2017-07-14';
     commit;
  END LOOP;  
END
/

create bitmap index test_index1 on T1(D1) LOCAL;
exec dbms_stats.gather_table_stats(ownname => '****',tabname => 'T1');
exec dbms_stats.gather_index_stats(ownname => '****',indname => 'TEST_INDEX1');



Смотрим план:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
explain plan for
select  *
from T1 T
where D1 in (TO_DATE('14072017','DDMMYYYY')
                      ,TO_DATE('15072017','DDMMYYYY')
                       );
select * from table(dbms_xplan.display);


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Plan hash value: 3955588149
 
---------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
---------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                            |             |   200K|  2539K|   294   (1)| 00:00:01 |       |       |
|   1 |  INLIST ITERATOR                            |             |       |       |            |          |       |       |
|   2 |   PARTITION RANGE ITERATOR                  |             |   200K|  2539K|   294   (1)| 00:00:01 |KEY(I) |KEY(I) |
|   3 |    TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| T1          |   200K|  2539K|   294   (1)| 00:00:01 |KEY(I) |KEY(I) |
|   4 |     BITMAP CONVERSION TO ROWIDS             |             |       |       |            |          |       |       |
|*  5 |      BITMAP INDEX SINGLE VALUE              | TEST_INDEX1 |       |       |            |          |KEY(I) |KEY(I) |
---------------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   5 - access("D1"=TO_DATE(' 2017-07-14 00:00:00', 'syyyy-mm-dd hh24:mi:ss') OR "D1"=TO_DATE(' 2017-07-15 
              00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
 
Note
-----
   - automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold


Прошу обратить внимание на стоимость извлечения 200К строк = 294.

Ниже просто для примера. Если кол-во партиций увиливать, то cost падает при пробеге по этому Bitmap т.е. видимо оракл делит кол-во различных значений индекса на общее кол-во строк и как-то эту информацию учитывает в cost.

Бага, фича, что-то забыли врубить на базе? Сам я не админ, возможно где-то "крыжик" не стоит. Ваше мнение? Зачем такой индекс не спрашивать, считайте для примера ).
...
Рейтинг: 0 / 0
14.07.2017, 09:28
    #39488840
AlexFF__|
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Pavel_PV,

У тебя в каждой партиции может быть до 86400 различных значений, а ты запрашиваешь только одно.
Что тут удивительного?
Попробуй гистограммы собрать.
...
Рейтинг: 0 / 0
14.07.2017, 09:57
    #39488860
kinky cat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Pavel_PV,
авторИнтересно что делаю не так?
авторЗачем такой индекс не спрашивать, считайте для примера ).
как то не получается)
дата и есть ключ партиционирования ??? и битмап по по ней ? это какое-то особое извращение?
Вроде, что многоблочный(direct?) фулл скан секции быстрей - сам понимаешь. Вопрос в том почему оптимизатор это сам не видит ?
...
Рейтинг: 0 / 0
14.07.2017, 11:25
    #39488930
Pavel_PV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
AlexFF__|Pavel_PV,

У тебя в каждой партиции может быть до 86400 различных значений, а ты запрашиваешь только одно.
Что тут удивительного?
Попробуй гистограммы собрать.
Дата транкейчена т.е. по факту 1 различное значение в каждой партиции. Плюс из плана видно, что оракл вполне себе корректно определяет кол-во извлекаемых строк. Гистограммы собирать пробовал, у меня не помогло ).

kinky cat , да извращение ещё. Но не поверишь нужно иногда, "bitmap and" отлично работает с этой штукой. Да вопрос больше не в том почему оптимизатор этого сам не видит, а в том что он вместо cost-а рисует какую-то басню. Он реально думает что достанет 200К строк, а cost рисует как будто их там десятки будут. Ниже пример приведу который нагляднее отразит ситуацию.

Так сказать раз там ничего удивительного, давай вот такой пример.
Создаем табличку так же как писал выше. Далее заполняем 4 партиции:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
declare
 vDate date;
BEGIN
  FOR i IN 1..100000
  LOOP
     vDate:= date '2017-07-14';
     insert into T1(D1,N) select vDate, i from dual;
  END LOOP;
  commit;
  --
  FOR i IN 1..4
  LOOP
     vDate:= date '2017-07-14' + i;
     insert/*+ ENABLE_PARALLEL_DML PARALLEL(8)*/ into T1(D1,N) select vDate, N from T1 where T1.D1 = date '2017-07-14';
     commit;
  END LOOP;  
END
/


Собираем статистику и смотрим план вот так, явно укажем хинтом идти по индексу чтобы отследить изменения cost-а:
Код: plsql
1.
2.
3.
4.
5.
6.
explain plan for
select/*+ index(T test_index1)*/  *
from T1 T
where D1 >= TO_DATE('14072017','DDMMYYYY')
 and D1 <=TO_DATE('15072017','DDMMYYYY');
select * from table(dbms_xplan.display); 


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Plan hash value: 890932065
 
--------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                  | Name        | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                           |             |   200K|  2539K|   923   (1)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE ITERATOR                  |             |   200K|  2539K|   923   (1)| 00:00:01 |    15 |    16 |
|   2 |   TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| T1          |   200K|  2539K|   923   (1)| 00:00:01 |    15 |    16 |
|   3 |    BITMAP CONVERSION TO ROWIDS             |             |       |       |            |          |       |       |
|*  4 |     BITMAP INDEX RANGE SCAN                | TEST_INDEX1 |       |       |            |          |    15 |    16 |
--------------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   4 - access("D1">=TO_DATE(' 2017-07-14 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "D1"<=TO_DATE(' 2017-07-15 
              00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
 
Note
-----
   - automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold


Cost = 923, видно что Pstart 15 и Pstop 16.

Теперь добавим в таблицу ещё одну партицию:
Код: plsql
1.
insert/*+ ENABLE_PARALLEL_DML PARALLEL(8)*/ into T1(D1,N) select date '2017-07-19', N from T1 where T1.D1 = date '2017-07-14';


Эти данные никак не влияют на верхний запрос с точки зрения информации, у нас ведь указана дата партицирования и просмотр индексов идёт только в партициях этой даты. Собираем статистику по таблице и по индексу. Ещё раз, по идее эти данные никак не влияют на верхний запрос верно? Проверим и получим такой план:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Plan hash value: 890932065
 
--------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                  | Name        | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                           |             |   200K|  2539K|   813   (1)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE ITERATOR                  |             |   200K|  2539K|   813   (1)| 00:00:01 |    15 |    16 |
|   2 |   TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| T1          |   200K|  2539K|   813   (1)| 00:00:01 |    15 |    16 |
|   3 |    BITMAP CONVERSION TO ROWIDS             |             |       |       |            |          |       |       |
|*  4 |     BITMAP INDEX RANGE SCAN                | TEST_INDEX1 |       |       |            |          |    15 |    16 |
--------------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   4 - access("D1">=TO_DATE(' 2017-07-14 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "D1"<=TO_DATE(' 2017-07-15 
              00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
 
Note
-----
   - automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold
 


Вроде бы всё так, но cost стал меньше. А так всё то же, партиции теже, строк столько же и байт столько же.

Ну давайте ещё одну партицию добавим:
Код: plsql
1.
insert/*+ ENABLE_PARALLEL_DML PARALLEL(8)*/ into T1(D1,N) select date '2017-07-20', N from T1 where T1.D1 = date '2017-07-14';


Смотрим план:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
 Plan hash value: 890932065
 
--------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                  | Name        | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                           |             |   200K|  2539K|   734   (1)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE ITERATOR                  |             |   200K|  2539K|   734   (1)| 00:00:01 |    15 |    16 |
|   2 |   TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| T1          |   200K|  2539K|   734   (1)| 00:00:01 |    15 |    16 |
|   3 |    BITMAP CONVERSION TO ROWIDS             |             |       |       |            |          |       |       |
|*  4 |     BITMAP INDEX RANGE SCAN                | TEST_INDEX1 |       |       |            |          |    15 |    16 |
--------------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   4 - access("D1">=TO_DATE(' 2017-07-14 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "D1"<=TO_DATE(' 2017-07-15 
              00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
 
Note
-----
   - automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold



При этом всё я следил за изменением cost при фуллскане, первый раз он был 334, потом 335 и потом 336. Т.е. никак не падает, действительно с чего бы ему падать? А cost в данном случае постоянно уменьшается, в один момент он становится меньше чем у full scan и появляется картина которую мы наблюдаем в первом моей сообщении.
...
Рейтинг: 0 / 0
14.07.2017, 11:33
    #39488944
Pavel_PV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Если кому-то интересно можно запилить такой же тест, только в качестве колонки для битмап взять не дату партицирования. Но зачем? Если ошибиться при доказательстве теоремы в первой строке, то какой смысл доказывать что-то дальше. Это я о формуле подсчета costa или о том, что где-то забыли что-то включить в оракле или собрать может статистику ещё.
Это бы поведение понять и ещё интересно на 11 версии всё так же?
...
Рейтинг: 0 / 0
14.07.2017, 11:37
    #39488949
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
А как статистику собираете?
...
Рейтинг: 0 / 0
14.07.2017, 11:40
    #39488953
Pavel_PV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
andrey_anonymousА как статистику собираете?

exec dbms_stats.gather_table_stats(ownname => '****',tabname => 'T1');
exec dbms_stats.gather_index_stats(ownname => '****',indname => 'TEST_INDEX1');
...
Рейтинг: 0 / 0
14.07.2017, 11:48
    #39488960
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Ни о чем не сказало - не вижу текущих настроек.
Попробуйте собирать без глобальной статистики.
...
Рейтинг: 0 / 0
14.07.2017, 12:04
    #39488977
Pavel_PV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
andrey_anonymousНи о чем не сказало - не вижу текущих настроек.
Попробуйте собирать без глобальной статистики.
Какие именно настройки нужны? Без глобальной всё ещё хуже, пробовал. Можно конечно кинуть готовый тест кейс, займёт не более 10 минут.
...
Рейтинг: 0 / 0
14.07.2017, 12:19
    #39488986
Maxim Demenko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Pavel_PV,
автор Но конечно глупость фуллсканить данные используя одноблочное чтение

Код: plsql
1.
TABLE ACCESS BY LOCAL INDEX ROWID BATCHED

делает/может делать multiblock reads

AlexFF__| У тебя в каждой партиции может быть до 86400 различных значений, а ты запрашиваешь только одно.
Что тут удивительного?
Попробуй гистограммы собрать

Код: plsql
1.
alter table t1 add constraint c1 check(d1=trunc(d1));


у меня на тестовой базе (12.2) план не меняет, так что, думаю, histograms тоже врядли изменят что то.

Regards

Maxim
...
Рейтинг: 0 / 0
14.07.2017, 12:25
    #39488991
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Pavel_PVandrey_anonymousНи о чем не сказало - не вижу текущих настроек.
Попробуйте собирать без глобальной статистики.
Какие именно настройки нужны? Без глобальной всё ещё хуже, пробовал. Можно конечно кинуть готовый тест кейс, займёт не более 10 минут.
Я имел ввиду те, что установлены посредством dbma_stats.SET_%_PREFS
Интересовала гранулярность и гистограммы.
Есть подозрение, что если добавление данных в новые секции влияет на оценки по существующим - то используется глобальная статистика.
Ну и конкретный метод построения гистограммы по проблемному полю тоже хотелось понять.
...
Рейтинг: 0 / 0
14.07.2017, 12:31
    #39489000
AlexFF__|
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Maxim DemenkoAlexFF__| У тебя в каждой партиции может быть до 86400 различных значений, а ты запрашиваешь только одно.
Что тут удивительного?
Попробуй гистограммы собрать

Код: plsql
1.
alter table t1 add constraint c1 check(d1=trunc(d1));


у меня на тестовой базе (12.2) план не меняет, так что, думаю, histograms тоже врядли изменят что то.
Maxim
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
-------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name        | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | Pstart| Pstop | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |             |      1 |        |       |   280 (100)|          |       |       |    200K|00:00:00.87 |    3022 |
|   1 |  INLIST ITERATOR                    |             |      1 |        |       |            |          |       |       |    200K|00:00:00.87 |    3022 |
|   2 |   PARTITION RANGE ITERATOR          |             |      2 |    207K|  4466K|   280  (20)| 00:00:03 |KEY(I) |KEY(I) |    200K|00:00:00.77 |    3022 |
|   3 |    TABLE ACCESS BY LOCAL INDEX ROWID| T1          |      2 |    207K|  4466K|   280  (20)| 00:00:03 |KEY(I) |KEY(I) |    200K|00:00:00.67 |    3022 |
|   4 |     BITMAP CONVERSION TO ROWIDS     |             |      2 |        |       |            |          |       |       |    200K|00:00:00.14 |      22 |
|*  5 |      BITMAP INDEX SINGLE VALUE      | TEST_INDEX1 |      2 |        |       |            |          |KEY(I) |KEY(I) |     20 |00:00:00.01 |      22 |
-------------------------------------------------------------------------------------------------------------------------------------------------------------



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
begin
  DBMS_STATS.GATHER_TABLE_STATS(
    ownname          => USER,
    tabname          => 'T1',
    estimate_percent => 100,
    method_opt       => 'FOR ALL COLUMNS SIZE AUTO',
    degree           => 16,
    granularity      => 'ALL',
    cascade          => true );
end;
/



Код: plsql
1.
2.
3.
4.
5.
6.
7.
-----------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation              | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | Pstart| Pstop | A-Rows |   A-Time   | Buffers |
-----------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |      |      1 |        |       |   132 (100)|          |       |       |    200K|00:00:00.26 |    3049 |
|   1 |  PARTITION RANGE INLIST|      |      1 |    200K|  2539K|   132   (4)| 00:00:02 |KEY(I) |KEY(I) |    200K|00:00:00.26 |    3049 |
|*  2 |   TABLE ACCESS FULL    | T1   |      2 |    200K|  2539K|   132   (4)| 00:00:02 |KEY(I) |KEY(I) |    200K|00:00:00.17 |    3049 |
-----------------------------------------------------------------------------------------------------------------------------------------
...
Рейтинг: 0 / 0
14.07.2017, 13:25
    #39489048
Maxim Demenko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
AlexFF__|,

12.2.0.1

Код: plsql
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.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
begin

  DBMS_STATS.GATHER_TABLE_STATS(

    ownname          => USER,

    tabname          => 'T1',

    estimate_percent => 100,

    method_opt       => 'FOR ALL COLUMNS SIZE AUTO',

    degree           => 16,

    granularity      => 'ALL',

    cascade          => true );

end;

/

PL/SQL procedure successfully completed.

SQL> SQL>

explain plan for

select  *

from T1 T

where D1 in (TO_DATE('14072017','DDMMYYYY')

                      ,TO_DATE('15072017','DDMMYYYY')

                       );

Explained.

SQL>

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------

Plan hash value: 1657369567

---------------------------------------------------------------------------------------------------------------------------

| Id  | Operation                                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |

---------------------------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                            |             |   200K|  2539K|   296   (0)| 00:00:01 |       |       |

|   1 |  INLIST ITERATOR                            |             |       |       |            |          |       |       |

|   2 |   PARTITION RANGE ITERATOR                  |             |   200K|  2539K|   296   (0)| 00:00:01 |KEY(I) |KEY(I) |

|*  3 |    TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| T1          |   200K|  2539K|   296   (0)| 00:00:01 |KEY(I) |KEY(I) |

|   4 |     BITMAP CONVERSION TO ROWIDS             |             |       |       |            |          |       |       |

|*  5 |      BITMAP INDEX SINGLE VALUE              | TEST_INDEX1 |       |       |            |          |KEY(I) |KEY(I) |

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------

--------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):

---------------------------------------------------

   3 - filter(TRUNC(INTERNAL_FUNCTION("D1"))=TO_DATE(' 2017-07-14 00:00:00', 'syyyy-mm-dd hh24:mi:ss') OR

              TRUNC(INTERNAL_FUNCTION("D1"))=TO_DATE(' 2017-07-15 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

   5 - access("D1"=TO_DATE(' 2017-07-14 00:00:00', 'syyyy-mm-dd hh24:mi:ss') OR "D1"=TO_DATE(' 2017-07-15

              00:00:00', 'syyyy-mm-dd hh24:mi:ss'))


Это с check constraint.
Без него
Код: plsql
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.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
SQL> alter table t1 drop constraint c1;

Table altered.

explain plan for

select  *

from T1 T

where D1 in (TO_DATE('14072017','DDMMYYYY')

                      ,TO_DATE('15072017','DDMMYYYY')

                       );

Explained.

SQL>

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------

Plan hash value: 1657369567

---------------------------------------------------------------------------------------------------------------------------

| Id  | Operation                                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |

---------------------------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                            |             |   200K|  2539K|   296   (0)| 00:00:01 |       |       |

|   1 |  INLIST ITERATOR                            |             |       |       |            |          |       |       |

|   2 |   PARTITION RANGE ITERATOR                  |             |   200K|  2539K|   296   (0)| 00:00:01 |KEY(I) |KEY(I) |

|   3 |    TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| T1          |   200K|  2539K|   296   (0)| 00:00:01 |KEY(I) |KEY(I) |

|   4 |     BITMAP CONVERSION TO ROWIDS             |             |       |       |            |          |       |       |

|*  5 |      BITMAP INDEX SINGLE VALUE              | TEST_INDEX1 |       |       |            |          |KEY(I) |KEY(I) |

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

   5 - access("D1"=TO_DATE(' 2017-07-14 00:00:00', 'syyyy-mm-dd hh24:mi:ss') OR "D1"=TO_DATE(' 2017-07-15

              00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

18 rows selected.



Regards

Maxim
...
Рейтинг: 0 / 0
14.07.2017, 13:27
    #39489054
Pavel_PV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
andrey_anonymous я думаю при сканировании нескольких партиций всегда используется глобальная статистика? ну до 12-ки так было, в 12-ке вроде у них появилась возможность собирать глобальную по партициям. Надо почитать и глянуть включён этот рычаг или нет.
Что именно установлено с помощью dbma_stats.SET_%_PREFS в выходные почитаю, если честно с ходу не могу сказать какие именно там параметры. Если нужно запулить пул настроек из конкретной вьюхи не вопрос, а так покурить надо эту тему ибо знаний в этой области маловато. Я просто к тому говорил, что если у тебя этот пример не повторяется то видимо есть смысл сравнить настройки систем, а иначе не совсем понятно что они дадут.


AlexFF__|, сделал констрэйнт и собрал статистику как в твоём примере и ничего не изменилось. Так же bitmap. Проверил на своей таблице с 4 партиями, как кост падал так и падает. Можешь подробнее, что именно крутил?
...
Рейтинг: 0 / 0
14.07.2017, 14:20
    #39489105
AlexFF__|
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Pavel_PVandrey_anonymous я думаю при сканировании нескольких партиций всегда используется глобальная статистика? ну до 12-ки так было, в 12-ке вроде у них появилась возможность собирать глобальную по партициям. Надо почитать и глянуть включён этот рычаг или нет.
Что именно установлено с помощью dbma_stats.SET_%_PREFS в выходные почитаю, если честно с ходу не могу сказать какие именно там параметры. Если нужно запулить пул настроек из конкретной вьюхи не вопрос, а так покурить надо эту тему ибо знаний в этой области маловато. Я просто к тому говорил, что если у тебя этот пример не повторяется то видимо есть смысл сравнить настройки систем, а иначе не совсем понятно что они дадут.


AlexFF__|, сделал констрэйнт и собрал статистику как в твоём примере и ничего не изменилось. Так же bitmap. Проверил на своей таблице с 4 партиями, как кост падал так и падает. Можешь подробнее, что именно крутил?
Да, действительно, гистограммы не причем.
Код: plsql
1.
2.
3.
4.
5.
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
"CORE  11.2.0.4.0  Production"
TNS for HPUX: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production


На первом примере я схалявил и выполнил без сбора статистики с dynamic sampling used for this statement (level=2)
А с твоим сбором сразу идет план с FTS.
Надо будет посмотреть 10053.
...
Рейтинг: 0 / 0
18.07.2017, 08:45
    #39490490
Pavel_PV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Проверил на честной 11.2.0.3, ничего не изменилось.

Снял 10053, надеюсь туда смотрю. Не совсем понимаю, что это даёт? :
Код: plsql
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.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
BASE STATISTICAL INFORMATION
***********************
Table Stats::
  Table: T1  Alias:  T  (Using composite stats)
  (making adjustments for partition skews)
  ORIGINAL VALUES::  #Rows: 10100000  SSZ: 0  LGR: 0  #Blks:  27970  AvgRowLen:  13.00  NEB: 0  ChainCnt:  0.00  SPC: 0  RFL: 0  RNF: 0  CBK: 0  CHR: 0  KQDFLG: 1
  #IMCUs: 0  IMCRowCnt: 0  IMCJournalRowCnt: 0  #IMCBlocks: 0  IMCQuotient: 0.000000
  PARTITIONS::
  PRUNED: 2
  ANALYZED: 2  UNANALYZED: 0
  #Rows: 10100000  SSZ: 0  LGR: 0  #Blks:  1276  AvgRowLen:  13.00  NEB: 0  ChainCnt:  0.00  SPC: 0  RFL: 0  RNF: 0  CBK: 0  CHR: 0  KQDFLG: 1
  #IMCUs: 0  IMCRowCnt: 0  IMCJournalRowCnt: 0  #IMCBlocks: 0  IMCQuotient: 0.000000
Index Stats::
  Index: TEST_INDEX1  Col#: 1
    USING COMPOSITE STATS
  LVLS: 1  #LB: 303  #DK: 101  LB/K: 3.00  DB/K: 5.00  CLUF: 505.00  NRW: 505.00 SSZ: 0.00 LGR: 0.00 CBK: 0.00 GQL: 0.00 CHR: 0.00 KQDFLG: 0 BSZ: 8192
  KKEISFLG: 1 
    ALL PARTITIONS USABLE
=======================================
SPD: BEGIN context at query block level
=======================================
Query Block SEL$1 (#0)
Return code in qosdSetupDirCtx4QB: NOCTX
=====================================
SPD: END context at query block level
=====================================
Access path analysis for T1
***************************************
SINGLE TABLE ACCESS PATH 
  Single Table Cardinality Estimation for T1[T] 
  SPD: Return code in qosdDSDirSetup: NOCTX, estType = TABLE

  Column (#1): 
    NewDensity:0.004950, OldDensity:0.000000 BktCnt:10100000.000000, PopBktCnt:10100000.000000, PopValCnt:101, NDV:101
  Column (#1): D1(DATE)
    AvgLen: 8 NDV: 101 Nulls: 0 Density: 0.004950 Min: 0.000000 Max: 2457949.000000
    Histogram: Freq  #Bkts: 101  UncompBkts: 10100000  EndPtVals: 101  ActualVal: no 
  Table: T1  Alias: T
    Card: Original: 10100000.000000  Rounded: 200001  Computed: 200000.500000  Non Adjusted: 200000.500000
  Scan IO  Cost (Disk) =   321.000000
  Scan CPU Cost (Disk) =   82201877.440000
  Total Scan IO  Cost  =   321.000000 (scan (Disk))
                         + 0.000000 (io filter eval) (= 0.000000 (per row) * 460765.105470 (#rows))
                       =   321.000000
  Total Scan CPU  Cost =   82201877.440000 (scan (Disk))
                         + 23494459.488738 (cpu filter eval) (= 50.990101 (per row) * 460765.105470 (#rows))
                       =   105696336.928738
  Access Path: TableScan
    Cost:  338.158496  Resp: 338.158496  Degree: 0
      Cost_io: 321.000000  Cost_cpu: 105696337
      Resp_io: 321.000000  Resp_cpu: 105696337
  ****** trying bitmap/domain indexes ******

 ****** Costing Index TEST_INDEX1
  SPD: Return code in qosdDSDirSetup: NOCTX, estType = INDEX_SCAN
  SPD: Return code in qosdDSDirSetup: NOCTX, estType = INDEX_FILTER
  Access Path: index (IndexOnly)
    Index: TEST_INDEX1
    resc_io: 8.000000  resc_cpu: 59172
    ix_sel: 0.019802  ix_sel_with_filters: 0.019802 
    Cost: 8.009606  Resp: 8.009606  Degree: 0
  Bitmap nodes:
    Used TEST_INDEX1
      Cost = 8.204514, sel = 0.019802
  Access path: Bitmap index - accepted
    Cost: 296.251030 Cost_io: 295.457315 Cost_cpu: 4889282.924506 Sel: 0.019802
    Not Believed to be index-only
  ****** finished trying bitmap/domain indexes ******
  Best:: AccessPath: IndexBitmap
         Cost: 296.251030  Degree: 1  Resp: 296.251030  Card: 200000.500000  Bytes: 0.000000
...
Рейтинг: 0 / 0
18.07.2017, 12:31
    #39490687
Pavel_PV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Проверил вот это:
****** Costing Index TEST_INDEX1
SPD: Return code in qosdDSDirSetup: NOCTX, estType = INDEX_SCAN
SPD: Return code in qosdDSDirSetup: NOCTX, estType = INDEX_FILTER
Access Path: index (IndexOnly)
Index: TEST_INDEX1
resc_io: 8.000000 resc_cpu: 59172
ix_sel: 0.400001 ix_sel_with_filters: 0.400001
Cost: 8.009606 Resp: 8.009606 Degree: 0
Bitmap nodes:
Used TEST_INDEX1
Cost = 8.204514, sel = 0.400001
Access path: Bitmap index - accepted
Cost: 923.229713 Cost_io: 916.113633 Cost_cpu: 43835051.745941 Sel: 0.400001
Not Believed to be index-only
Собственно создал так же табличку, но не 100 партиций а 4 добавил. Как видно Cost пробега по индексу пока выше чем cost фуллскана. У меня возможно глупый вопрос, вот этот Cost:
Cost: 923.229713 каким образом получается из Cost = 8.204514, sel = 0.400001
Ну понятно, что что-то где-то умножается. Не понимаю есть ли эти цифры в трэйс файле?
...
Рейтинг: 0 / 0
18.07.2017, 12:44
    #39490700
Pavel_PV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Ех...нумс продолжим монолог ).
Коллеги думаю дело в следующем. Вот строка из трэйс файла когда партиций много:
Cost = 8.204514, sel = 0.019802
А вот она же когда патиций мало:
Cost = 8.204514, sel = 0.400001

Sel я так понимаю селективность. Т.е. она падает с увеличением числа партиций, что конечно же вполне логично. Если этот параметр участвует в формировании итогового cost-а через знак "*", то....формулу бы.
...
Рейтинг: 0 / 0
18.07.2017, 12:52
    #39490712
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Pavel_PVформулу бы.
У Льюиса разве нет?
...
Рейтинг: 0 / 0
18.07.2017, 14:13
    #39490814
Pavel_PV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Про селективность что-то я "прогнал", не должна она падать. 1/100 000=2/200 000/=.... В этом наверное и соль?

У Льюиса наверное есть в его книжке про СВО. Но я не читал её.
...
Рейтинг: 0 / 0
28.07.2017, 10:20
    #39496491
Pavel_PV
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой?
Ещё покрутил тему пока было время.
Вот вырезка из трйэс файла:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
***************************************
BASE STATISTICAL INFORMATION
***********************
Table Stats::
  Table: T1  Alias:  T  (Using composite stats)
  (making adjustments for partition skews)
  ORIGINAL VALUES::  #Rows: 700002  SSZ: 0  LGR: 0  #Blks:  2669  AvgRowLen:  13.00  NEB: 0  ChainCnt:  0.00  SPC: 0  RFL: 0  RNF: 0  CBK: 0  CHR: 0  KQDFLG: 1
  #IMCUs: 0  IMCRowCnt: 0  IMCJournalRowCnt: 0  #IMCBlocks: 0  IMCQuotient: 0.000000
  PARTITIONS::
  PRUNED: 2
  ANALYZED: 2  UNANALYZED: 0
  #Rows: 700002  SSZ: 0  LGR: 0  #Blks:  1276  AvgRowLen:  13.00  NEB: 0  ChainCnt:  0.00  SPC: 0  RFL: 0  RNF: 0  CBK: 0  CHR: 0  KQDFLG: 1
  #IMCUs: 0  IMCRowCnt: 0  IMCJournalRowCnt: 0  #IMCBlocks: 0  IMCQuotient: 0.000000
Index Stats::
  Index: TEST_INDEX1  Col#: 1
    USING COMPOSITE STATS
  LVLS: 1  #LB: 21  #DK: 10  LB/K: 2.00  DB/K: 3.00  CLUF: 35.00  NRW: 35.00 SSZ: 0.00 LGR: 0.00 CBK: 0.00 GQL: 0.00 CHR: 0.00 KQDFLG: 0 BSZ: 8192
  KKEISFLG: 1 
    User hint to use this index
    ALL PARTITIONS USABLE
=======================================


Обратил внимание, что PRUNED=2 т.е. оракл понимает, что данные находятся только в 2 партициях. Но количество строк которое он при этом оценивает остаётся таким же как и общее количество строк в таблице т.е. 700 002. Может есть у кого мысли почему? Статистика и гистограммы в наличии.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Одно число строк дешевле выдернуть через bitmap одноблочкой через многоблочкой? / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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