Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.03.28;
Скачать: CL | DM;

Вниз

Есть-ли способ быстрее?   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.207 c
1-1078903558
Amirka
2004-03-10 10:25
2004.03.28
Вопрос по диалогу печати


3-1077803794
Pancha
2004-02-26 16:56
2004.03.28
Пипл! помогите с SQL запросом


14-1077956334
Юрий Федоров
2004-02-28 11:18
2004.03.28
Неплохо посидели


14-1078020663
SergP
2004-02-29 05:11
2004.03.28
О топиках, в которых никто не ответил вопрошающему.


11-1056994210
Vladimir Kladov
2003-06-30 21:30
2004.03.28
Скрипт загрузки новостей на странице KOL.