![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Есть-ли способ быстрее? [D6]
LaidBack © (2004-02-25 11:14:00)Сам далеко не специалист в Oracle, поэтому и вопрошаю помощи. Есть-ли быстрый способ получения количества записей в таблице (может как-нибудь через системные таблицы)? Нижеприведенный способ не подходит из-за тормозов на больших таблицах:
SELECT COUNT(*)FROM MY_TABLE
LaidBack (2004-02-26 09:21:00) [1]
> Плагин к чему, если не секрет?
К Database Workshop'у.
Хочу сделать свой плагин для Oracle, ну и заодно разобраться что к чему в ээтом монстре :)
Sergey13 (2004-02-26 09:15:00) [2]2LaidBack (26.02.04 09:01) [18]
>я пишу плагин для доступа к таблицам Oracle.
Плагин к чему, если не секрет?
>Естественно я не знаю ни базы, ни таблицы к которой его будут цеплять, но один из параметров который нужно вернуть, это RecordCount, а он, на моей тестовой таблице работает не так уж и быстро.
Ну тогда это скорее проблемы DBA, а не твои. Ибо юзер, задолбавшись ждать ответа, будет теребить своево DBA, а тот поправит это дело. 8-)
>Так что идеи на счет оптимизации таблицы мне не подходят.
Ну так я и говорю - пусть у DBA голова болит. Запрос у тебя нормальный.
>Была еще идея: таблицы до 1000 записей фетчить полностью, а большие кусками, но здесь снова нужно определять большие и маленькие...
А что будет делать твой плагин, когда сольет на клиента все 6000000 записей?
LaidBack (2004-02-26 09:01:00) [3]Дело вот в чем: я пишу плагин для доступа к таблицам Oracle. Естественно я не знаю ни базы, ни таблицы к которой его будут цеплять, но один из параметров который нужно вернуть, это RecordCount, а он, на моей тестовой таблице работает не так уж и быстро. Так что идеи на счет оптимизации таблицы мне не подходят. Была еще идея: таблицы до 1000 записей фетчить полностью, а большие кусками, но здесь снова нужно определять большие и маленькие...
Sergey13 (2004-02-26 08:48:00) [4]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 * тогда да, а так, сомневаюсь.
hCat (2004-02-25 17:09:00) [5]
> 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)
Второй вопрос, не связанный с первым, почему ваш запрос в ваших условиях имеет такой план исполнения. Чтобы дать на него ответ надо собрать достаточно много информации о вашем сервере, данных, методах расчета статистики и пр. Заниматься этим, честно говоря, лень.
Petr V. Abramov (2004-02-25 12:54:00) [6]> 36695 consistent gets
Либо в таблицу непрерывно кто-то пишет, либо что-то совсем плохо с базой.
roottim (2004-02-25 12:54:00) [7]что то ты не все привел...
аот мой пример
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указывает на тип оптимизатора... в данном случаеон настроен на выборку всех кортежей
LaidBack (2004-02-25 12:06:00) [8]
> Оптимизатор какой? Статистику собираешь?
Затрудняюсь ответить на счет оптимизатора...
Про статистику, это свойства таблицы LOGGED ?
Sergey13 (2004-02-25 11:59:00) [9]2LaidBack (25.02.04 11:50) [11]
Оптимизатор какой? Статистику собираешь? Странно что индексы не учавствуют.
LaidBack (2004-02-25 11:50:00) [10]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:50:00) [11]2LaidBack (25.02.04 11:31) [5]
А индекс давно не перестраивал?
roottim (2004-02-25 11:45:00) [12]хотя count(*) при нормально настроенном оптимизаторе и собранной статистике, тоже должен по индексу сканировать
ты бы показал план запроса...
sql> set autotrace on
sql> select count(*) from my_table
...
результат сюда
DenK_vrtz (2004-02-25 11:38:00) [13]попробуй
SELECT /*+FIRST ROWS*/ count(*) from MY_TABLE
roottim (2004-02-25 11:38:00) [14]SELECT COUNT(pk_field) FROM MY_TABLE
должен посчитать по индексу...
LaidBack (2004-02-25 11:31:00) [15]Индекс есть только первичный по Integer полю.
LaidBack (2004-02-25 11:31:00) [16]SELECT COUNT(*)FROM MY_TABLE
На таблице из 6.200.000 записей занял ~19 сек :-(
Версия Oracle 8.1.6
Sergey13 (2004-02-25 11:28:00) [17]2LaidBack (25.02.04 11:14)
А индекс на большой таблице есть? И сколько тормозит интересно?
DenK_vrtz (2004-02-25 11:26:00) [18]Версия Oracle какая?
Johnmen (2004-02-25 11:24:00) [19]Количество записей нигде не храниться. Вычисляется...
Danilka (2004-02-25 11:21:00) [20]большие таблицы, это сколько? на двух мильенах записей SELECT COUNT(*)FROM MY_TABLE
у меня отработал 0.05 сек...