Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Скорость выборки


Страницы:   1 2 3 4 5 6

Piter ©   (2004-12-18 18:50:00) 

Есть такое выражение:

'SELECT Count(n) From MyTable Where n=0'

Выборка длится около 4 секунд :(
Всего записей в базе 4700.

Почему так медленно? Правда, стоит заметить, что это только первый раз так долго. Потом такие выражения выполняются не более 100 мс, но все равно - загрузка программы происходит очень долго из-за этого.

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

Можно как-нибудь ускорить процесс? А то 4 секунды - это перебор все таки, имхо, на Athlon 1800. Не понимаю, как тогда работают базы с миллионами записей...

Использую базу Firebird Embedded


Nexel   (2004-12-20 12:01:00) [41]

Тэкс есть у меня инфа но это только для BDE! Вообщето когда работаем через жоп.. простите BDE то вначале (при ПЕРВОМ обращении) опрашивается структура и прочая "нужная" информация и кешируется далее пока TDatabase.Connected:=True то обращение идет просто мгновенно, чтобы юзать этот кэш повторно нужно в жоп... простите BDE указать следующее
SHEMA CACHE=True
CACHE DIR=Bla..bla..bla...
НО ПРИ ЛЮБОМ ИЗМЕНЕНИИ СТРУКУРЫ ТАБЛИЦ ВСЕ СОДЕРЖИМОЕ CACHE DIR надо удалять к ЕДРЕНИ ФЕНИ!


Anatoly Podgoretsky   (2004-12-20 11:50:00) [42]

jack128 ©   (20.12.04 11:48) [68]
Почему бы и нет, ведь идентифицировать записи как то нужно, а его нетути.


jack128   (2004-12-20 11:48:00) [43]

Нефига не понимаю. PLAN (TESTTABLE2 NATURAL)С какого боку тут влияет наличие или отсутствие ПК?


Sergey_Masloff   (2004-12-20 09:28:00) [44]

Да результат воспроизводимый - с PK всегда ощутимо быстрее при похожей статистике.


Sergey_Masloff   (2004-12-20 09:19:00) [45]

Итак предварительное резюме.
testtable
testtable2

две одинаковые по структуре таблицы (то что привел Piter и добавлено поле ID заполненое уникальными значениями). В таблице testtable2 объявлен первичный ключ по полю ID. Больше НИЧЕМ таблицы не отличаются.

Результаты ПЕРВОГО селекта после перестарта КОМПЬЮТЕРА

TESTTABLE2
Plan
PLAN (TESTTABLE2 NATURAL)

Adapted Plan
PLAN (TESTTABLE2 NATURAL)

------ Performance info ------
Prepare time = 0ms
Execute time = 68ms

Avg fetch time = 68.00 ms
Current memory = 674 260
Max memory = 758 924
Memory buffers = 2 048
Reads from disk to cache = 944
Writes from cache to disk = 6
Fetches from cache = 15 586

Таблица без ПК (в 2 раза дольше)

Plan
PLAN (TESTTABLE NATURAL)

Adapted Plan
PLAN (TESTTABLE NATURAL)

------ Performance info ------
Prepare time = 0ms
Execute time = 125ms

Avg fetch time = 125.00 ms
Current memory = 674 448
Max memory = 758 924
Memory buffers = 2 048
Reads from disk to cache = 920
Writes from cache to disk = 6
Fetches from cache = 16 359

То есть 3 секунды все равно не получаем то таблица с PK все равно стабильно обрабатывается БЫСТРЕЕ. Причем статистика примерно одинаковая так что потери времени скорее всего не на запросе а именно на чем-то типа построения индекса.


ЗВМ   (2004-12-20 08:57:00) [46]

А ты пускай выборку в потоке, программа запуститься сразу. А эти 4 секунды показывай заставку :)). Это на тот случай если ты не решишь данную проблему :)


Sergey_Masloff   (2004-12-20 08:28:00) [47]

Anatoly Podgoretsky ©   (20.12.04 00:47) [62]
>Кстати для подоьного запроса сервер может посчитать необходимым >построить временный индекс или что ни будь другое сделать.
Да временный индекс строится (потому что если в такую таблицу, уже заполненую, добавлять полный дубликат записи она скажет - как минимум одна запись с такими полями есть. И скажет не задумываясь). Правда мне не хватает знаний чтобы понять как этот индекс может оставаться доступным после перестарта сервиса IB и использующего его приложения. Нет, что страницы в кеше ОС невытеснены это понятно. Но что они доступны приложению...


sniknik   (2004-12-20 01:12:00) [48]

> А то просто второй вариант и у меня быстро отрабатывает. А вот count...
странно, у меня count работает на порядок быстрее чем полный селект. (так и должно в приципе)

задержка на первом есть, но не 4 сек, это точно... повторил предложенный код (чуть переделал под ADO. привычнее)
первый запуск предложенного селекта с count(*) около сек. (0,73 показало) второй 0,06.
в принципе логично, у меня не сервер, embeded, значит время на подгрузку dll, чтение страниц базы. нормально в общем...
при добавленом индексе время меньше но не намного, гдето 0,6 и 0,04 (всетаки влияет)
а вот простой селект с выборкой всех записей гдето 4 сек и даже немного больше получается (с ограничением n=3 0.66)

кстати интересно если сделать такую же таблицу в другой базе, и по ходу переключится с базы на базу то время первого селекта на ней сокращается с 0,6 (это уже с индексом) до 0,4сек. (меньше на время подгрузки dll ?)


Anatoly Podgoretsky   (2004-12-20 00:47:00) [49]

Кстати для подоьного запроса сервер может посчитать необходимым построить временный индекс или что ни будь другое сделать.
SELECT Count(n) From MyTable Where n=0


Anatoly Podgoretsky   (2004-12-20 00:43:00) [50]

Piter ©   (20.12.04 00:15) [59]
Срочно убегай :-)


AlterEgo of WondeRu   (2004-12-20 00:25:00) [51]

Piter ©   (20.12.04 0:15) [59]
а ты count делал? Или просто выборку select * ?
А то просто второй вариант и у меня быстро отрабатывает. А вот count...

чего голову морочишь? делай просто селект и проверяй Query1.RecordCount! и делай PK!


Piter   (2004-12-20 00:15:00) [52]

Anatoly Podgoretsky ©   (19.12.04 21:19) [56]
не знаю если в в win2000 система восстановления или нет


по-моему, нет

Sergey_Masloff   (19.12.04 21:21) [57]
У тебя что Primary Key в таблице нет? И в той на которой экспериментируешь ты - тоже?


видимо, нету :( Я привел SQL выражения для создания чистой таблицы. Привел программу заполнения этой таблицы. Больше ничего не делал...

А-а-а, чувствую меня сейчас будут бить... ногами...

Sergey_Masloff   (19.12.04 21:12) [55]
но конечно даже о секунде речи не идет


а ты count делал? Или просто выборку select * ?
А то просто второй вариант и у меня быстро отрабатывает. А вот count...


AlterEgo of WondeRu   (2004-12-19 23:47:00) [53]

Sergey_Masloff   (19.12.04 21:21) [57]
Отвечай срочно ;-)

отвечу за него: нет!!! причем PK нет ни в одной таблице его базы!


Sergey_Masloff   (2004-12-19 21:21:00) [54]

Piter ©   (19.12.04 18:55) [53]
>предлагаю провести эксперимент. Итак, делаем новую таблицу:
Секундочку! У тебя что Primary Key в таблице нет? И в той на которой экспериментируешь ты - тоже? ;-)

Отвечай срочно ;-)


Anatoly Podgoretsky   (2004-12-19 21:19:00) [55]

Piter ©   (19.12.04 18:59) [54]
Вы справшивайте - я отвечаю.
Это твоя задача задавать вопросы :-)

.gdb
В этом и может быть проблема, по рекомендация от производителей серверов этого типа, рекомендуется сменить расширение на .fdb, поскольку может быть снижение производительности именно того типа, которое ты и описываешь. Файлы .gdb являются системными и поэтому система их может (с делает) сохранять для восстановления.

в win2000?
Я не знаю если в в win2000 система восстановления или нет, но она есть даже на WinMe.


Sergey_Masloff   (2004-12-19 21:12:00) [56]

Piter ©   (19.12.04 18:55) [53]
Частично мне удалось повторить твой эксперимент. После перезагрузки компьютера первая выборка из твоей таблицы идет медленнее - почти в 6 раз но конечно даже о секунде речи не идет:

------ Performance info ------
Prepare time = 0ms
Execute time = 94ms
Avg fetch time = 94.00 ms
Current memory = 669 216
Max memory = 701 848
Memory buffers = 2 048
Reads from disk to cache = 848
Writes from cache to disk = 6
Fetches from cache = 15 431

В таблице 6500 записей сейчас проверяю одну идею.


Piter   (2004-12-19 18:59:00) [57]

Anatoly Podgoretsky ©   (19.12.04 17:03) [51]
вот сейчас по немногу начинаешь рассказывать подробности и то по немногу


я рассказал все, что считал нужным. Откуда я знаю что рассказывать? Может быть, имеет значение положение каталога с windows? Откуда я знаю? Вы справшивайте - я отвечаю.

Anatoly Podgoretsky ©   (19.12.04 17:03) [51]
Например до сих пор неизвестно имя файла сервера, например .fdb это одно, а .gdb


.gdb

Anatoly Podgoretsky ©   (19.12.04 17:03) [51]
тут и система восстонавления может оказаться задействованой.


в win2000?

Anatoly Podgoretsky ©   (19.12.04 17:03) [51]
По внешнем признакам или это кэш, или антивирус первый раз проверяет или система восстановления.


как я понял, это будет наблюдаться у любых систем. Можете проверить - тестовый пример я выложил.


Piter   (2004-12-19 18:55:00) [58]

Антивируса (монитора) - нет

sniknik ©   (19.12.04 16:41) [47]
может всетаки код виноват?


какой код? :)

Я эксперименты проводил в IBConsole - выполнял выборки. Какой тут код?

Sergey_Masloff   (19.12.04 16:46) [48]
Уже хотел ругаться что ответы не читаешь но понял что из-за глюков сервера мое огромное сообщение сюда не попало


используй мой клиент Magic Forum :)
Тогда твои посты пропадать не будут.

Sergey_Masloff   (19.12.04 16:46) [48]
Сервер и клиент у меня один физический компьютер


хорошо. У меня тоже

Sergey_Masloff   (19.12.04 16:46) [48]
После перегрузки СЕРВИСА IB его (а не операционки) кэш не существует как класс поэтому дальнейшие перезагрузки СЕРВЕРА по идее безразличны


Сергей! Ну что значит безразличны? Я ведь который пост говорю, что РАЗЛИЧНЫ!

Если компьютер не перезагружать - то вторичная выборка происходит за миллисекунды! При этом можно стартовать сервис IB, можно отключать его.
И с FB Embedded тоже само! По идее, он ведь при запуске каждый раз стартует? Ан нет, при повторном запуске программы все отлично, работает быстро. Тут видимо, кеширование операционки сказывается.

И только после перезагрузки в первый раз опять все медленно. Или можно не после перезагрузки - а например после интенсивной игры в какой-нибудь Call Of Duty. Тогда после выхода из игры опять выборка будет медленной в первый раз (видимо, ОС из-за игры убирает из кеша данные сервера).

Я когда проводил опыты - КАЖДЫЙ РАЗ ПЕРЕГРУЖАЛСЯ. Иначе экспериментировать не имеет смысла - время выборки при вторичных запросах очень маленькое. При этом можно хоть перегружать IB сервис, хоть нет. Да и вообще, это ведь справедливо и для FB Embedded, а там ведь при каждом запуске программы серверкак бы перезагружается.

В общем, похожая тема есть здесь - http://www.sql.ru/forum/actualthread.aspx?bid=2&tid=144344&pg=1

Nikolay M. ©   (19.12.04 16:50) [50]
А сделать базе сжатие-восстановление, если такое есть у ИБ?


Backup-Restore что ли? Есть такое у FB...

Sergey_Masloff   (19.12.04 16:48) [49]

предлагаю провести эксперимент. Итак, делаем новую таблицу:

Create Table TestTable ( n integer not null, TestI integer not null, TestI2 integer not null, TestBlob blob not null, TestDE DOUBLE PRECISION not null, TestSI smallint, TestVC varchar(100), TestVC2 varchar (50) )

Заполняем ее рандомными значениями. Я написал программу, вот ее исходники:
http://www.newmail.ru/messages/file.dhtml?file=www.piter007.newmail.ru/other/test_fill.zip

Листинг:

function RandomString(MaxCount: integer): string;
var
 i: integer;
begin
 Randomize;
 SetLength( Result, Random(MaxCount) + 1 );
 for i := 1 to Length(Result) do
   Result[i] := chr( Random(30) + 60 ) ;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 i: integer;
begin
 IBDatabase1.DatabaseName := EditBaseName.Text ;
 IBDatabase1.Open ;
 with IBQuery1 do
 begin
   SQL.Clear ;
   SQL.Add( 'INSERT INTO ' + EditTableName.Text
       + ' (n, TestI, TestI2, TestBlob, TestDE, TestSI, TestVC, TestVC2) VALUES'
       + ' (:pn, :pTestI, :pTestI2, :pTestBlob, :PTestDE, :pTestSI, :pTestVC, :pTestVC2)' );
   Randomize ;
   for i := 1 to StrToInt( EditInsertCount.Text ) do
     begin
       ParamByName('pn').AsInteger := Random(4);
       ParamByName('pTestI').AsInteger := Random(999999);
       ParamByName('pTestI2').AsInteger := Random(50);
       ParamByName('pTestBlob').AsBlob := RandomString(700);
       ParamByName('pTestDE').AsInteger := Random(9999999);
       ParamByName('pTestSI').AsInteger := Random(100);
       ParamByName('pTestVC').AsString := RandomString(90);
       ParamByName('pTestVC2').AsString := RandomString(40);
       ExecSQL ;
     end;
   IBTransaction1.Commit ;
 end;
end;


После заполнения таблицы 10000 записями - ПЕРЕЗАГРУЖАЕМ компьютер-сервер.
После чего, у меня выполнение
SELECT Count(n) FROM TestTable WHERE n=3
происходит чуть более секунды.

И это немного странно. С одной стороны, это явно меньше 3-4-х секунд в моем реальном примере, а с другой стороны здесь и общее, и при условии n=3 число записей больше. Число записей больше, а отрабатывает быстрее...
Новую таблицу я создавал прямо в своей реальной рабочей базе.

Но зато в реальной таблице число полей больше - может, в этом дело? Интересно...


Anatoly Podgoretsky   (2004-12-19 17:07:00) [59]

Piter ©   (19.12.04 16:33) [44]
На sql.ru хорошии специалисты, но по MS SQL
а по интербейсу и клонам лучшии на ibase.ru, но и там тоже будут гадать при такой подаче материала, хотя может быть и догадаются, попробовать то стоит?


Anatoly Podgoretsky   (2004-12-19 17:03:00) [60]

Piter ©   (19.12.04 16:02) [33]
А чего тут сомневаться, вот сейчас по немногу начинаешь рассказывать подробности и то по немногу.
Например до сих пор неизвестно имя файла сервера, например .fdb это одно, а .gdb совсем другое тут и система восстонавления может оказаться задействованой.

Например использование памяти в первом приближении можно посмотреть с помощью диспетчера задач, до запуска, дп первого запроса и после, после второго запроса и так далее. Эту информацию по использованию памяти ты не давал, и очень долго пришлось ждать прежде чем ты выдал информацию по объему памяти и винчестерам, а это все важная информация, которая может помочь в диагнозе.

По внешнем признакам или это кэш, или антивирус первый раз проверяет или система восстановления.


Страницы:   1 2 3 4 5 6

Наверх

Титульная страница Поиск, карта сайта Написать письмо