Форум: "Базы";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];
ВнизЕсть-ли способ быстрее? Найти похожие ветки
← →
LaidBack (2004-02-25 11:14) [0]Сам далеко не специалист в Oracle, поэтому и вопрошаю помощи. Есть-ли быстрый способ получения количества записей в таблице (может как-нибудь через системные таблицы)? Нижеприведенный способ не подходит из-за тормозов на больших таблицах:
SELECT COUNT(*)FROM MY_TABLE
← →
Danilka © (2004-02-25 11:21) [1]большие таблицы, это сколько? на двух мильенах записей SELECT COUNT(*)FROM MY_TABLE
у меня отработал 0.05 сек...
← →
Johnmen © (2004-02-25 11:24) [2]Количество записей нигде не храниться. Вычисляется...
← →
DenK_vrtz © (2004-02-25 11:26) [3]Версия Oracle какая?
← →
Sergey13 © (2004-02-25 11:28) [4]2LaidBack (25.02.04 11:14)
А индекс на большой таблице есть? И сколько тормозит интересно?
← →
LaidBack (2004-02-25 11:31) [5]SELECT COUNT(*)FROM MY_TABLE
На таблице из 6.200.000 записей занял ~19 сек :-(
Версия Oracle 8.1.6
← →
LaidBack (2004-02-25 11:31) [6]Индекс есть только первичный по Integer полю.
← →
roottim (2004-02-25 11:38) [7]SELECT COUNT(pk_field) FROM MY_TABLE
должен посчитать по индексу...
← →
DenK_vrtz © (2004-02-25 11:38) [8]попробуй
SELECT /*+FIRST ROWS*/ count(*) from MY_TABLE
← →
roottim (2004-02-25 11:45) [9]хотя count(*) при нормально настроенном оптимизаторе и собранной статистике, тоже должен по индексу сканировать
ты бы показал план запроса...sql> set autotrace on
sql> select count(*) from my_table
...
результат сюда
← →
Sergey13 © (2004-02-25 11:50) [10]2LaidBack (25.02.04 11:31) [5]
А индекс давно не перестраивал?
← →
LaidBack (2004-02-25 11:50) [11]set autotrace on
select count(*) from stat.ats_main
COUNT(*)
----------
6189990
1 row selected
Statistics
-----------------------------------------------------------
0 recursive calls
235 db block gets
36695 consistent gets
27433 physical reads
0 kcmccs called get current scn
0 index fast full scans (full)
0 index fast full scans (rowid ranges)
0 index fast full scans (direct read)
0 parse count (hard)
3 execute count
← →
Sergey13 © (2004-02-25 11:59) [12]2LaidBack (25.02.04 11:50) [11]
Оптимизатор какой? Статистику собираешь? Странно что индексы не учавствуют.
← →
LaidBack (2004-02-25 12:06) [13]
> Оптимизатор какой? Статистику собираешь?
Затрудняюсь ответить на счет оптимизатора...
Про статистику, это свойства таблицы LOGGED ?
← →
roottim (2004-02-25 12:54) [14]что то ты не все привел...
аот мой пример
SQL> set autotrace on
SQL> select count(*) from abonent
2 ;
COUNT(*)
----------
40079
План выполнения
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=10 Card=1)
1 0 SORT (AGGREGATE)
2 1 INDEX (FAST FULL SCAN) OF "PK_ABONENT" (UNIQUE) (Cost=10
Card=40079)
Статистика
----------------------------------------------------------
0 recursive calls
0 db block gets
92 consistent gets
0 physical reads
0 redo size
385 bytes sent via SQL*Net to client
499 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
Optimizer=ALL_ROWSуказывает на тип оптимизатора... в данном случае
он настроен на выборку всех кортежей
← →
Petr V. Abramov © (2004-02-25 12:54) [15]> 36695 consistent gets
Либо в таблицу непрерывно кто-то пишет, либо что-то совсем плохо с базой.
← →
hCat (2004-02-25 17:09) [16]
> LaidBack (25.02.04 11:14)
Первый вопрос который у меня возник:-"Зачем это надо ?". Мной написано немало систем на Оракл, но как-то всегда я обходился без знания о количестве строк в таблице. Допутим вы получили некотрое число - в нагруженной многопользовательской системе оно меняется каждую секунду. Как его использовать на клиенте ? Ладно бы было написано
select count(*)
from my_table
where pk_field = :aValue for update;
тогда это логично - мы залокировали некий набор и собираемся с ним работать и рисовать прогресс бар по мере обработки. Хотя такие вещи логично делать в сторнутых процедурах. Если же требуется просто узнать наличие записей в таблице, то это делается по другому, а именно так:
select count(*)
from dual
where exists (select 1 from my_table where rowNum = 1)
а наличие записи со значием PK равным заданному так:
select count(*)
from dual
where exists (select pk_fiels from my_table where pk_field = :value)
Второй вопрос, не связанный с первым, почему ваш запрос в ваших условиях имеет такой план исполнения. Чтобы дать на него ответ надо собрать достаточно много информации о вашем сервере, данных, методах расчета статистики и пр. Заниматься этим, честно говоря, лень.
← →
Sergey13 © (2004-02-26 08:48) [17]2LaidBack (25.02.04 12:06) [13]
>Затрудняюсь ответить на счет оптимизатора...
Какая версия Оракла? Есть 2 оптимизатора - по правилам и стоимостной. Второй по умолчанию (но с какой версии не помню, кажется, с 8.0).
>Про статистику, это свойства таблицы LOGGED ?
Нет, это то что собирается по команде
analyze table ....
желательно делать почаще и регулярно (частота зависит от интенсивности работы - оптимально, ИМХО, каждый день (ночь)). Это надо для стоимостного оптимизатора. Если статистики нет, используется оптимизатор по правилам. Хуже если статистика старая, ибо стоимостной оптимизатор строит план выполнения по неправильным вводным данным. Например в статистике сказано, что в таблице 6 записей, а на самом деле 6 млн. Оптимизатор решит, что проще отсканировать таблицу, чем использовать индекс. Что, ИМХО, у тебя и происходит.
Кроме того, я бы посоветовал, перестроить индексы.
2hCat (25.02.04 17:09) [16]
>select count(*)
>from my_table
>where pk_field = :aValue for update;
>тогда это логично - мы залокировали некий набор
Что то сомневаюсь я, однако. Вот если бы select * тогда да, а так, сомневаюсь.
← →
LaidBack (2004-02-26 09:01) [18]Дело вот в чем: я пишу плагин для доступа к таблицам Oracle. Естественно я не знаю ни базы, ни таблицы к которой его будут цеплять, но один из параметров который нужно вернуть, это RecordCount, а он, на моей тестовой таблице работает не так уж и быстро. Так что идеи на счет оптимизации таблицы мне не подходят. Была еще идея: таблицы до 1000 записей фетчить полностью, а большие кусками, но здесь снова нужно определять большие и маленькие...
← →
Sergey13 © (2004-02-26 09:15) [19]2LaidBack (26.02.04 09:01) [18]
>я пишу плагин для доступа к таблицам Oracle.
Плагин к чему, если не секрет?
>Естественно я не знаю ни базы, ни таблицы к которой его будут цеплять, но один из параметров который нужно вернуть, это RecordCount, а он, на моей тестовой таблице работает не так уж и быстро.
Ну тогда это скорее проблемы DBA, а не твои. Ибо юзер, задолбавшись ждать ответа, будет теребить своево DBA, а тот поправит это дело. 8-)
>Так что идеи на счет оптимизации таблицы мне не подходят.
Ну так я и говорю - пусть у DBA голова болит. Запрос у тебя нормальный.
>Была еще идея: таблицы до 1000 записей фетчить полностью, а большие кусками, но здесь снова нужно определять большие и маленькие...
А что будет делать твой плагин, когда сольет на клиента все 6000000 записей?
← →
LaidBack (2004-02-26 09:21) [20]
> Плагин к чему, если не секрет?
К Database Workshop"у.
Хочу сделать свой плагин для Oracle, ну и заодно разобраться что к чему в ээтом монстре :)
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.033 c