Select count(*) From - выполняется невероятно долго!!!

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
once77
Сообщения: 2
Зарегистрирован: 22 фев 2006, 14:04

Select count(*) From - выполняется невероятно долго!!!

Сообщение once77 » 22 фев 2006, 14:55

Привет всем.

Описание среды:
Работаю с FB 1.5.2. Есть две таблицы: Documents и DocumentsArchive.
Структура таблиц - идентичная. Когда приходят данные в систему они попадают в таблицу Documents, по истечению определенного времени, переносятся в DocumentsArchive. Часто пользователи работают только с таблицой Documents. Но, по желанию пользователя, возможно произвести работу и с таблицой DocumentsArchive.

Кол-во записей в таблице Documents: 53
Кол-во записей в таблице DocumentsArchive: 380200

Железо: Pentium IV HT 2800
RAM: 1 GB
HDD: 120 (зеркало)

Запрос
Select count(*) from "Documents"
UNION ALL
Select count(*) from "DocumentsArchive"

Привел к таким вот результатам:

План
PLAN (Documents NATURAL)
PLAN (DocumentsArchive NATURAL)

Адаптированный план
PLAN (Documents NATURAL) PLAN (DocumentsArchive NATURAL)

------ Performance info ------
Prepare time = 0ms
Execute time = 12m 57s 468ms
Avg fetch time = 388 734,00 ms
Current memory = 847 564
Max memory = 951 676
Memory buffers = 90
Reads from disk to cache = 380 776
Writes from cache to disk = 0
Fetches from cache = 1 521 542


Вопрос: Сейчас база содержит всего лишь 10% записей от предпологаемого кол-ва. Как ускорить поиск суммарного кол-ва записей по двум таблицам?

Заранее, спасибо.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 22 фев 2006, 15:23

что count по 380к записей выполняется 12 минут - верится с трудом. у меня count по 14 миллионам записей выполняется не дольше минуты. Вполне может быть, что тут влияет фрагментация записей блобами, если таковые есть в таблицах. Посмотри IBAnalyst-ом. И может быть ты напоролся на сборку мусора.

В любом случае count - это величина относительная, в версионнике может выполняться только полным просмотром всех версий записей, и как бы, не является операцией, которая выполняется быстро. То есть, я бы советовал подумать, зачем тебе count.

В крайнем случае есть трюк, которым можно очень быстро посчитать приблизительное количество записей для таблиц, у которых есть первичный ключ.

once77
Сообщения: 2
Зарегистрирован: 22 фев 2006, 14:04

Сообщение once77 » 22 фев 2006, 15:48

Вполне может быть, что тут влияет фрагментация записей блобами, если таковые есть в таблицах.
Таки, да. Сильная фрагментация блобами.
Спасибо. Попробую изменить структуру таблиц.

Касательно трюка - :)

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Re: Select count(*) From - выполняется невероятно долго!!!

Сообщение hvlad » 22 фев 2006, 16:11

once77 писал(а):------ Performance info ------
Prepare time = 0ms
Execute time = 12m 57s 468ms
Avg fetch time = 388 734,00 ms
Current memory = 847 564
Max memory = 951 676
Memory buffers = 90
Reads from disk to cache = 380 776
Writes from cache to disk = 0
Fetches from cache = 1 521 542
Это наверняка первое выполнение запроса.
90 буферов - очень мало

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 26 фев 2006, 08:52

Pentium IV HT 2800
Гиперпупинг включен? Выключи, от греха подальше. Версия сервера классик или супер?

А какой вообще смысл пересчета ВСЕХ записей в таблице, ну я могу понять подсчет документов какой-то одной категории... может он и не нужен совсем? :)

- Доктор когда я делаю так, мне больно...
- А Вы ТАК не делайте!

Ответить