Можно ли ускорить count в Oracle?
От: fmiracle  
Дата: 10.04.08 14:54
Оценка:
Проблема такая.
Есть база oracle. Есть прилада. Прилада выводит большое количество данных в постраничном режиме. При этом пользователь очень-очень хочет видеть не просто "вперед-назад" — а сколько в точности есть записей и сколько еще страниц осталось.

В результате используется count на данные по тому фильтру который наложил пользователь и показ одной текущей страницы для пользователя.

Результат. Разница между выборкой одной страницы и выполнением count — на несколько порядков.
(по относительно крупной таблице по достаточно "общему" фильтру получается вывод одной страницы занимает где-то в пределах сотой доли секунды, count — 5-10 секунд)

Быстродействие в результате ни к черту. Но заказчик твердо хочет видеть число записей, удовлетворяющих фильтру.

Можно ли как-то ускорить подсчет количества данных, удовлетворяющих фильтру? Индексы на поля, по которым фильтр проводится — наложены.
Re: Можно ли ускорить count в Oracle?
От: sunsquirel США  
Дата: 10.04.08 15:10
Оценка:
Здравствуйте, fmiracle, Вы писали:

F>Проблема такая.

F>Есть база oracle. Есть прилада. Прилада выводит большое количество данных в постраничном режиме. При этом пользователь очень-очень хочет видеть не просто "вперед-назад" — а сколько в точности есть записей и сколько еще страниц осталось.

F>В результате используется count на данные по тому фильтру который наложил пользователь и показ одной текущей страницы для пользователя.


F>Результат. Разница между выборкой одной страницы и выполнением count — на несколько порядков.

F>(по относительно крупной таблице по достаточно "общему" фильтру получается вывод одной страницы занимает где-то в пределах сотой доли секунды, count — 5-10 секунд)

F>Быстродействие в результате ни к черту. Но заказчик твердо хочет видеть число записей, удовлетворяющих фильтру.


F>Можно ли как-то ускорить подсчет количества данных, удовлетворяющих фильтру? Индексы на поля, по которым фильтр проводится — наложены.


Скажите, а Вы делаете count(*) или как?
Re: Можно ли ускорить count в Oracle?
От: wildwind Россия  
Дата: 10.04.08 15:39
Оценка:
Здравствуйте, fmiracle, Вы писали:

F>пользователь очень-очень хочет видеть не просто "вперед-назад" — а сколько в точности есть записей и сколько еще страниц осталось.


Желание обоснованное (бизнес-процессом) или аргументы типа "почему Access может а вы нет"?


F>(по относительно крупной таблице по достаточно "общему" фильтру получается вывод одной страницы занимает где-то в пределах сотой доли секунды, count — 5-10 секунд)

F>Быстродействие в результате ни к черту. Но заказчик твердо хочет видеть число записей, удовлетворяющих фильтру.

Если 5-10 секунд для заказчика приемлемы, то делайте count.

F>Можно ли как-то ускорить подсчет количества данных, удовлетворяющих фильтру? Индексы на поля, по которым фильтр проводится — наложены.


Кардинально нет. Можно использовать аналитику (count over) и обойтись одним запросом. Заодно и результаты будут согласованными, в отличие от отдельного count.
Re[2]: Можно ли ускорить count в Oracle?
От: fmiracle  
Дата: 10.04.08 18:13
Оценка:
Здравствуйте, sunsquirel, Вы писали:

S>Скажите, а Вы делаете count(*) или как?


count(*)
Re: Можно ли ускорить count в Oracle?
От: Аноним  
Дата: 11.04.08 04:40
Оценка:
Нужно посмотреть explain plan, используются ли индексы вообще? Какой медод доступа к базе (ADO, OO4O) ?
Разница от того, что Ораклу для count(*) надо всё-таки данные перебрать все чтобы получить точное количество результирующих записей, а для пары-тройки несортированых записей скорость на порядок быстрее.
По моему опыту, OO4O работает со страницами гораздо лучше. Смотреть тут http://www.orafaq.com/faqoo4o.htm
В зависимости от количества данных и предназначения запроса может иметь смысл огранизовать специальную таблицу в которой будут собираться все интересующие записи, готовые к выводу на экран. И уже на эту таблицу накладывать фильтры, считать количество записей и т.д.
Re: Можно ли ускорить count в Oracle?
От: Neco  
Дата: 19.04.08 09:57
Оценка:
F>Быстродействие в результате ни к черту. Но заказчик твердо хочет видеть число записей, удовлетворяющих фильтру.
а индекс на таблице есть?
может hiwatermark высоко задран и таблицу нужно реорганизовать?
сколько всего строк в таблице?
всю ночь не ем, весь день не сплю — устаю
Re[2]: Можно ли ускорить count в Oracle?
От: JazzzMaster Россия  
Дата: 22.04.08 11:44
Оценка:
Здравствуйте, Neco, Вы писали:

N>может hiwatermark высоко задран и таблицу нужно реорганизовать?


кстати, интересно, а можно ли его как-нибудь "понизить" не используя truncate ?
... << RSDN@Home 1.2.0 alpha rev. 745>>
Re[3]: Можно ли ускорить count в Oracle?
От: wildwind Россия  
Дата: 24.04.08 11:43
Оценка:
Здравствуйте, JazzzMaster, Вы писали:

N>>может hiwatermark высоко задран и таблицу нужно реорганизовать?

JM>кстати, интересно, а можно ли его как-нибудь "понизить" не используя truncate ?

drop/create.
Re[3]: Можно ли ускорить count в Oracle?
От: Neco  
Дата: 24.04.08 18:58
Оценка: 1 (1)
JM>кстати, интересно, а можно ли его как-нибудь "понизить" не используя truncate ?
alter table move?
всю ночь не ем, весь день не сплю — устаю
Re[2]: Можно ли ускорить count в Oracle?
От: krot_av  
Дата: 28.04.08 07:37
Оценка: -1
Здравствуйте, Аноним, Вы писали:
А>Разница от того, что Ораклу для count(*) надо всё-таки данные перебрать все чтобы получить точное количество результирующих записей, а для пары-тройки несортированых записей скорость на порядок быстрее.

Нет никакой разницы, count(*) или count(1). Это все urban legend миллион раз опровергнутые. Execution plan пбсолютно одинаков, к тому же
в каждой1 второй книжке по оптимизации постоянно пишут, что скорость выборки не зависит от количества полей перечисляемых в запросе.
Re[3]: Можно ли ускорить count в Oracle?
От: wildwind Россия  
Дата: 28.04.08 13:30
Оценка:
Здравствуйте, krot_av, Вы писали:

_>Нет никакой разницы, count(*) или count(1). Это все urban legend миллион раз опровергнутые.

К чему здесь этот флуд? Никто не предлагал count(1).

_>скорость выборки не зависит от количества полей перечисляемых в запросе.

А это неверно.
Re[4]: Можно ли ускорить count в Oracle?
От: krot_av  
Дата: 29.04.08 07:39
Оценка:
Здравствуйте, wildwind, Вы писали:

_>>скорость выборки не зависит от количества полей перечисляемых в запросе.

W>А это неверно.
Execution plan будет одинаковым, вся разница только в передаваемых объемах данных по сети.
Re[5]: Можно ли ускорить count в Oracle?
От: wildwind Россия  
Дата: 29.04.08 07:46
Оценка:
Здравствуйте, krot_av, Вы писали:

_>>>скорость выборки не зависит от количества полей перечисляемых в запросе.

W>>А это неверно.
_>Execution plan будет одинаковым, вся разница только в передаваемых объемах данных по сети.
И это неверно. Подумай об индексах.
Re[6]: Можно ли ускорить count в Oracle?
От: krot_av  
Дата: 29.04.08 11:41
Оценка:
Здравствуйте, wildwind, Вы писали:

W>И это неверно. Подумай об индексах.

Использование индексов зависит не от полей перечисленных в select, а от условий WHERE.
Так что никакого влияние на индексы select * или select some field не окажет, да и не должен оказывать.
Re[7]: Можно ли ускорить count в Oracle?
От: wildwind Россия  
Дата: 29.04.08 13:12
Оценка:
Здравствуйте, krot_av, Вы писали:

W>>И это неверно. Подумай об индексах.

_>Использование индексов зависит не от полей перечисленных в select, а от условий WHERE.
_>Так что никакого влияние на индексы select * или select some field не окажет, да и не должен оказывать.

Не упорствуй в своем заблуждении. Сравни планы для "select pk from table" и "select * from table" для обычной (heap) таблицы.
Re[8]: Можно ли ускорить count в Oracle?
От: krot_av  
Дата: 29.04.08 13:18
Оценка:
Здравствуйте, wildwind, Вы писали:


W>Не упорствуй в своем заблуждении. Сравни планы для "select pk from table" и "select * from table" для обычной (heap) таблицы.


Я их сравнивал в оракл и DB2.
Если говоритиь о заблуждениях, то будет тебе известно, что для приведенных тобой запросов будет использован full scan в любом случае.
Re[9]: Можно ли ускорить count в Oracle?
От: wildwind Россия  
Дата: 29.04.08 18:06
Оценка:
Здравствуйте, krot_av, Вы писали:

_>Здравствуйте, wildwind, Вы писали:



W>>Не упорствуй в своем заблуждении. Сравни планы для "select pk from table" и "select * from table" для обычной (heap) таблицы.


_>Я их сравнивал в оракл и DB2.

Продемонстрируй! Или просто скажи что проверять было лень.

Вот мой пример:

SQL> create table test_tab as select rownum id, rpad('*', 2000, '*') text from all_objects;

Таблица создана.

SQL> alter table test_tab add constraint test_tab_pk primary key (id);

Таблица изменена.

SQL> exec dbms_stats.gather_table_stats(user, 'test_tab', cascade => true)

Процедура PL/SQL успешно завершена.

SQL> set autotrace traceonly
SQL> set timing on
SQL> select * from test_tab;

83692 строк выбрано.

Затрач.время: 00:00:09.34

План выполнения
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=8264 Card=83692 Bytes=167802460)
   1    0   TABLE ACCESS (FULL) OF 'TEST_TAB' (Cost=8264 Card=83692 Bytes=167802460)

Статистика
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      83706  consistent gets
      83692  physical reads
          0  redo size
    1274661  bytes sent via SQL*Net to client
      61730  bytes received via SQL*Net from client
       5581  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      83692  rows processed

SQL> select id from test_tab;

83692 строк выбрано.

Затрач.время: 00:00:05.93

План выполнения
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=40 Card=83692 Bytes=418460)
   1    0   INDEX (FAST FULL SCAN) OF 'TEST_TAB_PK' (UNIQUE) (Cost=40 Card=83692 Bytes=418460)

Статистика
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       5915  consistent gets
        357  physical reads
          0  redo size
     949057  bytes sent via SQL*Net to client
      61730  bytes received via SQL*Net from client
       5581  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      83692  rows processed

SQL> disc
Отсоединено от Oracle9i Enterprise Edition Release 9.2.0.7.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.7.0 - Production


_>Если говоритиь о заблуждениях, то будет тебе известно, что для приведенных тобой запросов будет использован full scan в любом случае.

full scan он разный бывает.
Re[4]: Можно ли ускорить count в Oracle?
От: seregaa Ниоткуда http://blogtani.ru
Дата: 29.04.08 20:19
Оценка:
Здравствуйте, Neco, Вы писали:

JM>>кстати, интересно, а можно ли его как-нибудь "понизить" не используя truncate ?

N>alter table move?
а для индексов — alter index rebuild tablespace
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[10]: Можно ли ускорить count в Oracle?
От: JazzzMaster Россия  
Дата: 04.05.08 12:18
Оценка:
Здравствуйте, wildwind, Вы писали:

_>>Если говоритиь о заблуждениях, то будет тебе известно, что для приведенных тобой запросов будет использован full scan в любом случае.

W>full scan он разный бывает.

Странно, но мне то же самое поведение смоделировать не удалось. В обоих случаях случаях был использован full scan

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (FULL) OF 'T1'


Oracle правда восьмой

SQL> select banner from v$version;

BANNER
----------------------------------------------------------------
Oracle8i Enterprise Edition Release 8.1.7.4.0 — Production
PL/SQL Release 8.1.7.4.0 — Production
CORE 8.1.7.0.0 Production

TNS for Solaris: Version 8.1.7.4.0 — Production
NLSRTL Version 3.4.1.0.0 — Production

... << RSDN@Home 1.2.0 alpha rev. 745>>
Re[3]: Можно ли ускорить count в Oracle?
От: Niteshade Россия  
Дата: 05.05.08 02:15
Оценка:
_>в каждой1 второй книжке по оптимизации постоянно пишут, что скорость выборки не зависит от количества полей перечисляемых в запросе.
если идет сканирование по индексу и все поля в кляузе select входят в этот индекс, то, разумеется, такой запрос будет отрабатывать эффективнее, т.к. позволяет брать данные напрямую из индекса, избегая, например, table access by rowid для Oracle(либо аналогов для других СУБД)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.