powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Каким образом выполяется count(*) и как его можно потимизировать
25 сообщений из 57, страница 1 из 3
Каким образом выполяется count(*) и как его можно потимизировать
    #39554351
helgisbox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
Каким образом выполяется count(*) и как его можно потимизировать
    #39554369
explain plan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
helgisboxсовпадает с числом блоков самого "компактного" индексаCовпадение. Построй регулярный индекс по полю, где большинство значений null. Он будет самым компактным.

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

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

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

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

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

авторOracle 11.2.0.4.
...
Рейтинг: 0 / 0
Каким образом выполяется count(*) и как его можно потимизировать
    #39554622
Фотография Shtock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dba_tab_modification
...
Рейтинг: 0 / 0
Каким образом выполяется count(*) и как его можно потимизировать
    #39554639
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Каким образом выполяется count(*) и как его можно потимизировать
    #39554732
Bobby Z.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Каким образом выполяется count(*) и как его можно потимизировать
    #39554740
Bobby Z.и обновлять раз в суткине только обновлять, но селектить раз в сутки
helgisboxРаз в сутки, нужно просто видеть динамику.
...
Рейтинг: 0 / 0
Каким образом выполяется count(*) и как его можно потимизировать
    #39554754
Фотография Vladimir Filin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
helgisboxРаз в сутки, нужно просто видеть динамику.
Как вариант, sample_clause:
https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_10002.htm#i2065953

Нужно будет подбирать размер и оценивать точность
...
Рейтинг: 0 / 0
Каким образом выполяется count(*) и как его можно потимизировать
    #39554864
helgisbox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем откликнувшимся. В принципе - скорость отработки запроса не критична. Есть какой-нибудь флаг оптимизатору, чтобы он распараллеливал конкретно в таком запросе не по дефолту, а всего на 2 - 4 процесса сам запрос? В принципе - будет все равно, даже если он отрабатывать будет полчаса. Он же таблицу на "апдейты и инсерты" в такое время не лочит ;)
...
Рейтинг: 0 / 0
Каким образом выполяется count(*) и как его можно потимизировать
    #39554891
alter session
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
helgisboxне лочитзато параллель сбрасывает грязные буферы на диск и затем физически читает. Производительность других операций может существенно просесть на системе со слабым io. Если таблиц много, лучше запускать несколько джобов по подмножеству таблиц.
...
Рейтинг: 0 / 0
Каким образом выполяется count(*) и как его можно потимизировать
    #39555014
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почему в указанных условиях не использовать результаты штатного сбора статистики?
...
Рейтинг: 0 / 0
Каким образом выполяется count(*) и как его можно потимизировать
    #39555191
Relict_35
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2andrey_anonymous так имеешь ввиду?:
Код: sql
1.
2.
3.
select num_rows
from all_tаbles
where table_name = 'имя'
...
Рейтинг: 0 / 0
Каким образом выполяется count(*) и как его можно потимизировать
    #39555244
Bobby Z.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Каким образом выполяется count(*) и как его можно потимизировать
    #39555259
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bobby Z.А NOPARALLEL вообще запретит выполнять запрос параллельно, равно как и
Код: plsql
1.
ALTER TABLE TAB NOPARALLEL;

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

Зависит от того, насколько важна точность и как часто собирается статистика.
Раз в сутки, нужно просто видеть динамику. Иногда существенные изменения связаны с определенными регламентами, которые нужно корректировать. В оперативных таблицах это не так заметно, а вот данные с накоплением - там видно. Смущает, когда такой запрос своим фуллсканом по индексу минут пять держит пачку распараллеленных запросов.
не мучай базу - смотри в статистику
...
Рейтинг: 0 / 0
Каким образом выполяется count(*) и как его можно потимизировать
    #39556401
Bobby Z.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Каким образом выполяется count(*) и как его можно потимизировать
    #39556416
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
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
Каким образом выполяется count(*) и как его можно потимизировать
    #39556444
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Каким образом выполяется count(*) и как его можно потимизировать
    #39556466
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
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
Каким образом выполяется count(*) и как его можно потимизировать
    #39556475
Bobby Z.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Каким образом выполяется count(*) и как его можно потимизировать
    #39556486
Bobby Z.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
25 сообщений из 57, страница 1 из 3
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Каким образом выполяется count(*) и как его можно потимизировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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