Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Каким образом выполяется count(*) и как его можно потимизировать / 25 сообщений из 57, страница 1 из 3
16.11.2017, 14:20
    #39554351
helgisbox
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
Oracle 11.2.0.4.

Сделал по нескольким таблицам несколько запросов "select count(*) from <table_name>" и просмотрел по ним статистику. Выяснилось следующее:

1) Число обращений к диску примерно равно числу блоков в том из индексов и которого по dba_segments меньше всего блоков;
2) Число блоков индекса на 0,5% - 2,8% больше числа обращений к диску;
3) Число листьев в соответствующих индексах leaf_blocks составляет примерно 20% от общего числа, и при этом blevel везде равен 2.

Число блоков в индексах было диапазоне 30 тыс - 900 тыс. Статистика в сессии собиралась включением: "set autotrace on statistics". Размеры таблиц в блоках на порядок больше размеров индексов. Судя по плану запросов - каждый раз идет именно фулл скан индексов.

Собственно вопросы:
1) Это совпадение, что число обращений к диску так совпадает с числом блоков самого "компактного" индекса?
2) Если получение count(*) из таблицы делается по компактному индексу, то почему не достаточно было добраться до первого листа, а затем только по ним вести пересчет сократив время почти в 2 раза (при blevel = 2 это было бы равно числу блоков + 3),разве листья не ссылаются на следующий элемент в цепочке?
3) Можно ли каким-нибудь образом уменьшить число обращений к диску для таких запросов?
...
Рейтинг: 0 / 0
16.11.2017, 14:34
    #39554369
explain plan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
helgisboxсовпадает с числом блоков самого "компактного" индексаCовпадение. Построй регулярный индекс по полю, где большинство значений null. Он будет самым компактным.

helgisbox не достаточно было добраться до первого листаНе внятно кому-куда достаточно добраться. По количеству логических чтений, достаточно пройти по листам - IFS, но это одноблочные чтения. IFFS дешевле по io. Хотя на ssd, не отягощенном префетчами, последовательное или случайное чтение - без разницы.

helgisbox3) Можно ли каким-нибудь образом уменьшить число обращений к диску для таких запросов?Да. количество обращений к диску можно сократить до нуля. Просто не считать бесполезные count(*).
...
Рейтинг: 0 / 0
16.11.2017, 15:30
    #39554413
helgisbox
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
explain planhelgisboxсовпадает с числом блоков самого "компактного" индексаCовпадение. Построй регулярный индекс по полю, где большинство значений null. Он будет самым компактным.

helgisbox не достаточно было добраться до первого листаНе внятно кому-куда достаточно добраться. По количеству логических чтений, достаточно пройти по листам - IFS, но это одноблочные чтения. IFFS дешевле по io. Хотя на ssd, не отягощенном префетчами, последовательное или случайное чтение - без разницы.

helgisbox3) Можно ли каким-нибудь образом уменьшить число обращений к диску для таких запросов?Да. количество обращений к диску можно сократить до нуля. Просто не считать бесполезные count(*).

1. Стало быть, если он даже в план включил этот индекс, то он знал, что поле не может принимать значения null или является ключевым.
2. У меня не SSD случай.
3. Если не count(*), то что будет полезным для получения числа строк таблицы?
...
Рейтинг: 0 / 0
16.11.2017, 15:39
    #39554429
tru55
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
helgisbox3. Если не count(*), то что будет полезным для получения числа строк таблицы?
Зависит от того, насколько важна точность и как часто собирается статистика.
...
Рейтинг: 0 / 0
16.11.2017, 15:48
    #39554446
helgisbox
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
tru55helgisbox3. Если не count(*), то что будет полезным для получения числа строк таблицы?
Зависит от того, насколько важна точность и как часто собирается статистика.
Раз в сутки, нужно просто видеть динамику. Иногда существенные изменения связаны с определенными регламентами, которые нужно корректировать. В оперативных таблицах это не так заметно, а вот данные с накоплением - там видно. Смущает, когда такой запрос своим фуллсканом по индексу минут пять держит пачку распараллеленных запросов.
...
Рейтинг: 0 / 0
16.11.2017, 15:59
    #39554459
Shtock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
...
Рейтинг: 0 / 0
16.11.2017, 16:34
    #39554485
K790
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
Shtock,

авторOracle 11.2.0.4.
...
Рейтинг: 0 / 0
16.11.2017, 18:35
    #39554622
Shtock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
dba_tab_modification
...
Рейтинг: 0 / 0
16.11.2017, 19:07
    #39554639
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
Shtockdba_tab_modification

Код: plaintext
1.
2.
INSERTS	NUMBER	 	 Approximate  number of inserts since the last time statistics were gathered
UPDATES	NUMBER	 	 Approximate  number of updates since the last time statistics were gathered
DELETES	NUMBER	 	 Approximate  number of deletes since the last time statistics were gathered

SY.
...
Рейтинг: 0 / 0
17.11.2017, 00:02
    #39554732
Bobby Z.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
helgisboxСмущает, когда такой запрос своим фуллсканом по индексу минут пять держит пачку распараллеленных запросов.
Мнээ... Вот с этого места поподробнее - что тут как кого держит?

А по существу, если точность и своевременность не [очень] важна, то можно ещё вот так:

init.ora:
Код: sql
1.
2.
query_rewrite_enabled=true;
query_rewrite_integrity=stale_tolerated;


Код: plsql
1.
2.
3.
4.
5.
create materialized view <table>_rcmw 
enable query rewrite
refresh on demand
as
select count(*) cnt from <table>;


и обновлять раз в сутки ночью или ранним утром в бэкграунде. Тогда select count(*) from <table> будет выполняться вообще мгновенно.
...
Рейтинг: 0 / 0
17.11.2017, 00:16
    #39554740
Каким образом выполяется count(*) и как его можно потимизировать
Bobby Z.и обновлять раз в суткине только обновлять, но селектить раз в сутки
helgisboxРаз в сутки, нужно просто видеть динамику.
...
Рейтинг: 0 / 0
17.11.2017, 02:00
    #39554754
Vladimir Filin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
helgisboxРаз в сутки, нужно просто видеть динамику.
Как вариант, sample_clause:
https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_10002.htm#i2065953

Нужно будет подбирать размер и оценивать точность
...
Рейтинг: 0 / 0
17.11.2017, 09:46
    #39554864
helgisbox
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
Спасибо всем откликнувшимся. В принципе - скорость отработки запроса не критична. Есть какой-нибудь флаг оптимизатору, чтобы он распараллеливал конкретно в таком запросе не по дефолту, а всего на 2 - 4 процесса сам запрос? В принципе - будет все равно, даже если он отрабатывать будет полчаса. Он же таблицу на "апдейты и инсерты" в такое время не лочит ;)
...
Рейтинг: 0 / 0
17.11.2017, 10:25
    #39554891
alter session
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
helgisboxне лочитзато параллель сбрасывает грязные буферы на диск и затем физически читает. Производительность других операций может существенно просесть на системе со слабым io. Если таблиц много, лучше запускать несколько джобов по подмножеству таблиц.
...
Рейтинг: 0 / 0
17.11.2017, 12:21
    #39555014
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
Почему в указанных условиях не использовать результаты штатного сбора статистики?
...
Рейтинг: 0 / 0
17.11.2017, 16:11
    #39555191
Relict_35
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
2andrey_anonymous так имеешь ввиду?:
Код: sql
1.
2.
3.
select num_rows
from all_tаbles
where table_name = 'имя'
...
Рейтинг: 0 / 0
17.11.2017, 17:14
    #39555244
Bobby Z.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
helgisboxЕсть какой-нибудь флаг оптимизатору, чтобы он распараллеливал конкретно в таком запросе не по дефолту, а всего на 2 - 4 процесса сам запрос? Хинт PARALLEL принимает в качестве аргумента DOP (degree of parallelism), так что если написать, скажем,
Код: plsql
1.
SELECT /*+ PARALLEL(4) */ COUNT(*) FROM TAB;

, то 4 параллельных процесса (+QC) этот запрос и будут выполнять. А NOPARALLEL вообще запретит выполнять запрос параллельно, равно как и
Код: plsql
1.
ALTER TABLE TAB NOPARALLEL;

приведёт к тому, что запросы без хинтов будут выполняться последовательно.
...
Рейтинг: 0 / 0
17.11.2017, 17:34
    #39555259
AlexFF__|
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
Bobby Z.А NOPARALLEL вообще запретит выполнять запрос параллельно, равно как и
Код: plsql
1.
ALTER TABLE TAB NOPARALLEL;

приведёт к тому, что запросы без хинтов будут выполняться последовательно.
Ну как бы случаи разные бывают =)
Код: plsql
1.
alter session force parallel query
...
Рейтинг: 0 / 0
18.11.2017, 00:52
    #39555381
Ivan Durak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
helgisboxtru55пропущено...

Зависит от того, насколько важна точность и как часто собирается статистика.
Раз в сутки, нужно просто видеть динамику. Иногда существенные изменения связаны с определенными регламентами, которые нужно корректировать. В оперативных таблицах это не так заметно, а вот данные с накоплением - там видно. Смущает, когда такой запрос своим фуллсканом по индексу минут пять держит пачку распараллеленных запросов.
не мучай базу - смотри в статистику
...
Рейтинг: 0 / 0
20.11.2017, 21:07
    #39556401
Bobby Z.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
AlexFF__|Bobby Z.А NOPARALLEL вообще запретит выполнять запрос параллельно, равно как и
Код: plsql
1.
ALTER TABLE TAB NOPARALLEL;

приведёт к тому, что запросы без хинтов будут выполняться последовательно.
Ну как бы случаи разные бывают =)
Код: plsql
1.
alter session force parallel query

А зачем? И какой DOP будет? А если я после этого в той же сессии сделаю
Код: plsql
1.
alter session set events '10384 trace name context forever, level 16384'

то тогда что будет?
...
Рейтинг: 0 / 0
20.11.2017, 21:45
    #39556416
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
Bobby Z.
Код: plsql
1.
alter session set events '10384 trace name context forever, level 16384'

к слову такая "параллель" может быть быстрее чем при таком же но не параллельном плане за счет безусловных direct path reads в отличие от adaptive serial direct path reads :)
...
Рейтинг: 0 / 0
20.11.2017, 23:04
    #39556444
AlexFF__|
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
Bobby Z.AlexFF__|пропущено...

Ну как бы случаи разные бывают =)
Код: plsql
1.
alter session force parallel query

А зачем? И какой DOP будет? А если я после этого в той же сессии сделаю
Код: plsql
1.
alter session set events '10384 trace name context forever, level 16384'

то тогда что будет?
Ты хочешь, чтобы я за тебя проверил?
Мне не надо, я знаю как это работает )
А вот ты с помощью тестов мог бы увидеть, как форсирование parallel dml позволяет системе самой определить DOP на твоей "непараллеливаемой" таблице с ALTER TABLE TAB NOPARALLEL;
Если конечно система решит параллелить, чего, впрочем, не трудно добиться.
...
Рейтинг: 0 / 0
20.11.2017, 23:57
    #39556466
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
Bobby Z.
Код: plsql
1.
ALTER TABLE TAB NOPARALLEL;


приведёт к тому, что запросы без хинтов будут выполняться последовательно.ну это не правда...
простенький пример:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
alter system set parallel_max_servers=16;
alter system set parallel_degree_limit=8;
alter system set parallel_min_time_threshold=1 scope=memory;
drop table t purge;

create table t noparallel as select dummy, rpad(level,400) padding from dual connect by level<=1000;
call dbms_stats.gather_table_stats('','t');
call dbms_stats.set_table_stats(user,'T',numrows => 1e7, numblks => 1e6);

alter table t parallel 4;
select t.degree from user_tables t where table_name='T';

alter table t noparallel;
select t.degree from user_tables t where table_name='T';

pause;

alter session set parallel_degree_policy=auto;

explain plan for update t set dummy='Y';
select * from table(dbms_xplan.display);
pause;


результат
Код: 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.
SQL> alter system set parallel_max_servers=16;
SQL> alter system set parallel_degree_limit=8;
SQL> alter system set parallel_min_time_threshold=1 scope=memory;
SQL> alter table t noparallel;

Table altered.

SQL> select t.degree from user_tables t where table_name='T';

DEGREE
----------------------------------------
         1

1 row selected.

SQL> alter session set parallel_degree_policy=auto;

Session altered.

SQL> explain plan for update t set dummy='Y';

Explained.

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

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------
Plan hash value: 1378397380

---------------------------------------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT      |          |    10M|    19M|   100K  (1)| 00:00:04 |        |      |            |
|   1 |  UPDATE               | T        |       |       |            |          |        |      |            |
|   2 |   PX COORDINATOR      |          |       |       |            |          |        |      |            |
|   3 |    PX SEND QC (RANDOM)| :TQ10000 |    10M|    19M|   100K  (1)| 00:00:04 |  Q1,00 | P->S | QC (RAND)  |
|   4 |     PX BLOCK ITERATOR |          |    10M|    19M|   100K  (1)| 00:00:04 |  Q1,00 | PCWC |            |
|   5 |      TABLE ACCESS FULL| T        |    10M|    19M|   100K  (1)| 00:00:04 |  Q1,00 | PCWP |            |
---------------------------------------------------------------------------------------------------------------

Note
-----
   - automatic DOP: Computed Degree of Parallelism is 3



nb: это не параллельный дмл!
...
Рейтинг: 0 / 0
21.11.2017, 01:08
    #39556475
Bobby Z.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
AlexFF__|Bobby Z.пропущено...
А зачем? И какой DOP будет? А если я после этого в той же сессии сделаю
Код: plsql
1.
alter session set events '10384 trace name context forever, level 16384'

то тогда что будет?
Ты хочешь, чтобы я за тебя проверил?
Мне не надо, я знаю как это работает )
А вот ты с помощью тестов мог бы увидеть, как форсирование parallel dml позволяет системе самой определить DOP на твоей "непараллеливаемой" таблице с ALTER TABLE TAB NOPARALLEL;
Если конечно система решит параллелить, чего, впрочем, не трудно добиться.Ну молодец, что знаешь. Хотя тогда должен бы знать, что тут и проверять нечего и тесты никакие не нужны, и форсирование parallel dml ну никакой совершенно роли не играет в этом случае. Или я не понял что "это" ты знаешь как работает?
...
Рейтинг: 0 / 0
21.11.2017, 01:46
    #39556486
Bobby Z.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Каким образом выполяется count(*) и как его можно потимизировать
xtenderBobby Z.
Код: plsql
1.
ALTER TABLE TAB NOPARALLEL;


приведёт к тому, что запросы без хинтов будут выполняться последовательно.ну это не правда...
Код: plsql
1.
alter session set parallel_degree_policy=auto;

Ну нет, мы так не договаривались..! AutoDOP до сих пор вообще не упоминался, ОП не привёл вообще никаких parallel* параметров, то есть считаем, что всё по умолчанию, а по умолчанию в 11.2.0.4 parallel_degree_policy=manual. AutoDOP это вообще отдельная, длинная и грустная песня, не к ночи будь помянута (и Ваш пример тому лишнее подтверждение). Так что давайте не будем меряться. А ты вы тут уже начали изгаляться кто знает круче способ нае..ть заставить Оракл что-то выполнить или не выполнить параллельно (да и я вместе с вами, не удержался :) ). Здорово, конечно, что вы тут все такие опытные и разных фокусов умеете, но как это помогает ОП?
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Каким образом выполяется count(*) и как его можно потимизировать / 25 сообщений из 57, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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