Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];

Вниз

Скорость выборки   Найти похожие ветки 

 
Piter ©   (2004-12-18 18:50) [0]

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

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

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

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

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

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

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


 
Anatoly Podgoretsky ©   (2004-12-18 18:53) [1]

Индекс по полю N и добавить памяти в компьютер.


 
AlterEgo of WondeRu ©   (2004-12-18 18:57) [2]

{+оффтоп}
Piter ©   (18.12.04 18:50)
Использую базу Firebird Embedded

испоьзуй нормальный Firebird, с ним у меня никогда проблем не возникало
{-оффтоп}


 
Piter ©   (2004-12-18 19:12) [3]

Anatoly Podgoretsky ©   (18.12.04 18:53) [1]
Индекс по полю N


индекс по полю N есть. Причем что он есть, что его нету - пофигу.

и добавить памяти в компьютер.

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


 
Piter ©   (2004-12-18 19:13) [4]

AlterEgo of WondeRu ©   (18.12.04 18:57) [2]
испоьзуй нормальный Firebird, с ним у меня никогда проблем не возникало


а почему бы Oracle не посоветовать?

Если я использую Firebird Embedded, то значит это чем-то обоснованно.

Да и на обычном Firebird тоже самое


 
AlterEgo of WondeRu ©   (2004-12-18 19:20) [5]

Piter ©   (18.12.04 19:13) [4]
совет. а попробуй инициализацию проводить на другой таблице! т.е. хотя бы на анкетах, она же пустая!


 
Sergey_Masloff   (2004-12-18 20:17) [6]

Piter ©   (18.12.04 18:50)
А не сборка ли энто мусора? 4 сек на 5000 записей многовато конечно но - точно не оно?


 
Piter ©   (2004-12-18 20:38) [7]

AlterEgo of WondeRu ©   (18.12.04 19:20) [5]
совет. а попробуй инициализацию проводить на другой таблице


Хм, инциализацию данной таблицы проводить на другой таблице? Как ты себе это представляешь...


 
Piter ©   (2004-12-18 20:39) [8]

Sergey_Masloff   (18.12.04 20:17) [6]
А не сборка ли энто мусора?


в смысле?


 
DrPass ©   (2004-12-18 20:42) [9]

Транзакции убирают мусор, который оставили их предшественники. Если до этого у тебя проводились масштабные операции удаления/обновления, сборка мусора займет заметное время.


 
Sergey_Masloff   (2004-12-18 20:47) [10]

Piter ©   (18.12.04 20:39) [8]
>в смысле?
В прямом. Во время работы много DELETE и UPDATE?
Мое предположение такое (если тормоз на 1 выборке):
1) Во время работы программы идет много апдейтов и удалений
2) При каждом изменении-удалении IB создает "версии" записей. Рано или поздно версии становятся "мусором" и помечаются соответствующим флагом. При следующем обращении к записи IB видит последнюю и старые мусорные версии и удаляет мусор. Это занимает время.

Эксперимент:
1) СОздаешь таблицу с 100000 записей
2) Делаешь DELETE FROM YOURTABLE
3) Делаешь COMMIT
4) Делаешь SELECT COUNT(*) FROM YOURTABLE
5) Наслаждаешься наблюдением диких тормозов N времени при приличной загрузке процессора интербейзом.


 
Sergey_Masloff   (2004-12-18 20:49) [11]

Ну в смысле 100000 тебя притормозит значительно дольше чем на 4 секунды, возможно успеешь кофе сходить попить ;-) А твои 5000 если из них апдейтилось процентов 30 пару-тройку секунд могут дать.


 
Piter ©   (2004-12-18 22:47) [12]

Piter ©   (18.12.04 18:50)
Правда, стоит заметить, что это только первый раз так долго. Потом такие выражения выполняются не более 100 мс, но все равно - загрузка программы происходит очень долго из-за этого


То есть, данная выборка делается в начале работы программы. И делается она очень долго почему-то.

А так как firebird embedded, то наверное никакого там мусора не остается.

Если закрыть программу, а потом опять открыть - то все будет быстро отрабатывать. Если перезагрузиться, то опять в первый раз будут тормоза.

P.S. Page Size = 4096, если это важно...


 
DrPass ©   (2004-12-18 22:58) [13]

Подозреваю, что проблема в таком случае кроется не в СУБД, а в операционке. Win9x?
Возможно, просто файл БД хочет дефрагментации. Попробуй сначала backup-restore, потом дефрагментацию


 
Sergey_Masloff   (2004-12-18 23:30) [14]

Piter ©   (18.12.04 22:47) [12]
>То есть, данная выборка делается в начале работы программы. И >делается она очень долго почему-то.
Никакого противоречия. До закрытия программы у тебя висит заинтересованная транзакция и мусора нет. В момент закрытия происходит автокоммит и все ненужное становится мусором.

>А так как firebird embedded, то наверное никакого там мусора не >остается.
А что ембеддед запрещает параллельные транзакции одного приложения? И они механизм версионности переписали специально для emb? Сомневаюсь (уверен что это не так).

Вобщем, экспериментируй. Уверен что это именно выборка тормозит? Если сделаешь select first(1) from MyTable Where n=0 тормозит также? A select * from MyTable Where ID = 0? Если да то это не сборщик мусора а иначе проверяй дальше. Отключи допустим сборку мусора. Или перед запуском программы сделай базе бэкап-рестор. При этом гарантировано в базе мусора нет - те же тормоза?


 
Nikolay M. ©   (2004-12-18 23:31) [15]

А какие еще есть значения, кроме 0? Если только 0/1, то, конечно, индекс при выборке не будет использоваться, будет тупой scan table.


 
Piter ©   (2004-12-19 00:36) [16]

DrPass ©   (18.12.04 22:58) [13]
Win9x?


win2000

Возможно, просто файл БД хочет дефрагментации

а почему повторно запрос отрабатывает очень быстро, да и впоследствии все работает хорошо?


 
Piter ©   (2004-12-19 00:48) [17]

Sergey_Masloff   (18.12.04 23:30) [14]
Никакого противоречия. До закрытия программы у тебя висит заинтересованная транзакция и мусора нет. В момент закрытия происходит автокоммит и все ненужное становится мусором


НУ хорошо, хорошо. А как ты объяснишь:

Piter ©   (18.12.04 22:47) [12]
Если закрыть программу, а потом опять открыть - то все будет быстро отрабатывать. Если перезагрузиться, то опять в первый раз будут тормоза.


Nikolay M. ©   (18.12.04 23:31) [15]
А какие еще есть значения, кроме 0?


0-15 где-то...

Если только 0/1, то, конечно, индекс при выборке не будет использоваться

а почему?


 
SergP ©   (2004-12-19 01:50) [18]

Хм... У меня с access"ом аналогичная ситуация...
Да и ранее наблюдал такое и с MySQL и с Oracle.
Первый запрос после подключения к базе всегда долго отрабатывается...

А что касается акцесса, то первый запуск проги долго отрабатывается (там призапуске идет подключение к базе и несколько запросов), при следующих запусках все сравнительно быстро. Но если почистить память, то следующий запуск снова долго происходит.

ИМХО то что в твоем случае - вполне нормально.


 
Piter ©   (2004-12-19 03:20) [19]

SergP ©   (19.12.04 1:50) [18]
Первый запрос после подключения к базе всегда долго отрабатывается


ну не 4 секунды же...


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

Piter ©   (19.12.04 00:48) [17]

>НУ хорошо, хорошо. А как ты объяснишь:
>Piter ©   (18.12.04 22:47) [12]
>Если закрыть программу, а потом опять открыть

см. [14] 3 абзац. Если сделано то опиши результаты. Если нет то не вижу базы для дальнейших теоретических рассуждений. Причин может быть миллион и если просто в уме их перебирать - не хватит жизни. Знаешь же метод двоичного спуска? Так чтобы отсекать половинки нужны эксперименты, без этого никак.


 
AlterEgo of WondeRu ©   (2004-12-19 13:13) [21]

Piter ©   (18.12.04 20:38) [7]
Хм, инциализацию данной таблицы проводить на другой таблице? Как ты себе это представляешь...

у тебя данный запрос первый идет? или до него еще есть какие-либо запросы? как быстро они выполняются?

поробуй выполнить свой запрос в IBExpert"e


 
Nikolay M. ©   (2004-12-19 14:02) [22]


> Piter ©   (19.12.04 00:48) [17]
> А какие еще есть значения, кроме 0?
>
> 0-15 где-то...
>
> Если только 0/1, то, конечно, индекс при выборке не будет
> использоваться
>
> а почему?

Тогда похоже на то. Посмотри план своего запроса, подозреваю, что индекс в нем не используется.
А как ты представляешь себе грамотную индексацию поля, в котором есть, скажем, только значения 0/1?


 
Piter ©   (2004-12-19 14:56) [23]

Nikolay M. ©   (19.12.04 14:02) [22]
Тогда похоже на то


что тогда похоже на то? :)
Я просто спросил - почему. Реально значения не только 0-1

А как ты представляешь себе грамотную индексацию поля, в котором есть, скажем, только значения 0/1?

а я вообще себе индексацию не представляю :(

или до него еще есть какие-либо запросы?

есть, но из других таблиц


 
DrPass ©   (2004-12-19 14:59) [24]


> Возможно, просто файл БД хочет дефрагментации
>
> а почему повторно запрос отрабатывает очень быстро, да и
> впоследствии все работает хорошо?

Потому что кешируется операционкой. Подозреваю, что файл не слишком большой. Кроме того, 4700 записей - это ничтожный размер даже для тупого перебора без индексов, 4 сек. тут многовато


 
Sergey_Masloff   (2004-12-19 15:01) [25]

Nikolay M. ©   (19.12.04 14:02) [22]
В таблице 4000 записей. Есть индекс, нет индекса, используется он или нет - на современном компьютере и интербейзе он все равно 4 секунды не будет выполняться.


 
Anatoly Podgoretsky ©   (2004-12-19 15:05) [26]

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


 
Nikolay M. ©   (2004-12-19 15:06) [27]


> Sergey_Masloff   (19.12.04 15:01) [25]

А где написано про современный компьютер? Атлон 1800? Дык может у автора памяти 64 и винт на 2?

Тут еще встречал советы по поводу расширения у файла БД - какие-то расширения винда считает своими (слышал звон...). Точнее не скажу, т.к. с ИБ не работаю.


 
Sergey_Masloff   (2004-12-19 15:12) [28]

Nikolay M. ©   (19.12.04 15:06) [27]
>А где написано про современный компьютер?
Я имею в виду начиная с DX4-100 c 32Mb RAM.

У меня есть система работающая уже скоро 8 лет, из них 6 я к ней не прикасался. Сервер IBM PC/2 DX2-66 16 Mb RAM (вернее на моей памяти доставляли до 32 Mb) 6 пользователей в одноранговой сети. Таблица из 4000 записей - это семечки даже для такой "системы".


 
Piter ©   (2004-12-19 15:34) [29]

Итак, опыты провожу в IBConsole (ну нету у меня IBExpert и трафика нет, чтобы скачать):

1) SELECT count(n) FROM Tree WHERE n=3

Execution Time: 3:0297
Prepare Time: 0
Starting Memory: 9141244
Current Memory: 9180156
Delta Memory: 38912
Number of buffers: 2048
Reads: 752
Writes: 5
Plan: PLAN(TREE INDEX(TREE_ID))

Запрос вернул Count=2206

При повторном запуске числа практически теже, только:

Execution Time: 0:0016

2) select first(1) from Tree Where n=3

Token unknown - line 1, char 17
from

3) select * from Tree Where n=3

Execution Time: 0:0094
Prepare Time: 0:0031
Starting Memory: 9151480
Current Memory: 9195512
Delta Memory: 44032
Number of buffers: 2048
Reads: 74
Writes: 9
Plan: PLAN(TREE INDEX(TREE_ID))

Повторный запрос выполняется вообще за время ноль :)

Если после
select * from Tree Where n=3
выполнить
SELECT count(n) FROM Tree WHERE n=3
- то последний все равно выполняется больше 3-х секунд.


 
Nikolay M. ©   (2004-12-19 15:44) [30]


> PLAN(TREE INDEX(TREE_ID))

Какие поля входят в этот индекс? И как называется индекс по полю n? Не знаю точно, как это будет у ИБ, но, имхо, индекс по n тут не используется. ы?

Кстати, могу еще предположить, что у ИБ count() работает как-то хитро, попробуй удалить индекс на n и повторить эксперимент?


 
Sergey_Masloff   (2004-12-19 15:55) [31]

Piter ©   (19.12.04 15:34) [29]
Да интересная ситуация. Уж и так и сяк гоняю никак больше 16 мс не могу заставить выполняться. Ни о каких секундах речи нет... :(

Ну еще напрягись сделай не count(n) a count(*) тем более в твоем контексте это одно и то же.

Ну а так все же может фича ембеддеда - ведь это dll-ка которая загружается только при запуске твоей программы. Ей свой кэш тоже надо распределять и так далее - может поэтому первый запрос с интенсивным подъемом страниц в память так тормозит?


 
Sergey_Masloff   (2004-12-19 15:56) [32]

Nikolay M. ©   (19.12.04 15:44) [30]

>попробуй удалить индекс на n и повторить эксперимент?
Кстати очень хорошая мысль!


 
Piter ©   (2004-12-19 16:02) [33]

Anatoly Podgoretsky ©   (19.12.04 15:05) [26]
в чем сомневаюсь


извините, но можете сомневаться дальше

DrPass ©   (19.12.04 14:59) [24]
Подозреваю, что файл не слишком большой


28 Мб.

Nikolay M. ©   (19.12.04 15:06) [27]
Атлон 1800? Дык может у автора памяти 64 и винт на 2?


80 Gb барракуда + 256 Mb DDR 2100

Sergey_Masloff   (19.12.04 15:12) [28]
Таблица из 4000 записей - это семечки даже для такой "системы".


Сергей, а вы учитываете что я говорю про ПЕРВЫЙ ЗАПУСК. У вас там думаю крутится сервер базы данных и крутится. Повторные запросы и у меня отрабатываются очень быстро. Можете посмотреть выше - я привел статистику. Но вот САМЫЙ ПЕРВЫЙ ЗАПРОС после перезагрузки - очень медленно работает.

Вы проведите эксперимент - вырубите базу данных на вашем DX2-66 сервере, перезагрузите компьютер, запустите сервер - и посмотрите сколько будет выполняться хотя бы первый count(*) по любой таблице, где записей хотя бы пару тысяч.


 
Piter ©   (2004-12-19 16:04) [34]

Nikolay M. ©   (19.12.04 15:44) [30]
Какие поля входят в этот индекс?


CREATE INDEX TREE_ID ON TREE (n)

Просто название неудачное, остался от прежнего:

CREATE INDEX TREE_ID ON TREE (n, ID);


 
Piter ©   (2004-12-19 16:04) [35]

Sergey_Masloff   (19.12.04 15:55) [31]
Уж и так и сяк гоняю никак больше 16 мс не могу заставить выполняться


бли-и-ин. А вы перезагружались??!?!?!


 
Nikolay M. ©   (2004-12-19 16:14) [36]


> CREATE INDEX TREE_ID ON TREE (n)
>
> Просто название неудачное, остался от прежнего:
>
> CREATE INDEX TREE_ID ON TREE (n, ID);

Тогда, скорее всего, остался мусор в страницах от предыдущего индекса. Удали и создай заново.


 
Nikolay M. ©   (2004-12-19 16:16) [37]


> Sergey_Masloff   (19.12.04 15:55) [31]
> Ну а так все же может фича ембеддеда - ведь это dll-ка которая
> загружается только при запуске твоей программы. Ей свой
> кэш тоже надо распределять и так далее - может поэтому первый
> запрос с интенсивным подъемом страниц в память так тормозит?

И из-за этого план запроса требует кол-во чтений на порядок больше, судя по [29]?


 
Sergey_Masloff   (2004-12-19 16:18) [38]

Piter ©   (19.12.04 16:04) [35]
>бли-и-ин. А вы перезагружались??!?!?!
Да, и сервис перестартовывал и даже (хотя это уже не играет роли) компьютер перезагружал. Одно и то же.


 
Sergey_Masloff   (2004-12-19 16:20) [39]

Ну вобщем COUNT(*) по 50 000 000 записей 52 секунды без индексов. После перезагрузки компьютера ;-)


 
Piter ©   (2004-12-19 16:25) [40]

Sergey_Masloff   (19.12.04 15:55) [31]
ведь это dll-ка которая загружается только при запуске твоей программы. Ей свой кэш тоже надо распределять и так далее - может поэтому первый запрос с интенсивным подъемом страниц в память так тормозит


а серверу Interbase не надо в первый раз поднимать страницы в память?
К тому же - приведенные мной опыты я делал уже на сервере Firebird (использовал IBConsole) - никакой разницы между Embedded и сервером не замечено

Nikolay M. ©   (19.12.04 15:44) [30]
попробуй удалить индекс на n и повторить эксперимент?


Дропнул индекс по N. Запрос выполняется еще дольше:

SELECT count(n) FROM Tree WHERE n=3 :

Execution Time: 4:0672 - время увеличилось
Prepare Time: 0:0000
Delta Memory: 6144 - маленькой какой-то стала
Number of buffers: 2048
Reads: 1118 - увеличилось
Writes: 6
Plan: PLAN(TREE NATURAL)



Страницы: 1 2 3 вся ветка

Форум: "Базы";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.05 c
14-1105685336
WondeRu
2005-01-14 09:48
2005.02.06
Управляем мобилой устройствами по RS-232! Хочу, но как?


1-1106402537
Павел
2005-01-22 17:02
2005.02.06
Панель в TreeList


9-1099264534
Кто---то
2004-11-01 02:15
2005.02.06
Как в GLScene сделать рамочку выделения области ? Как в Фотошопе


3-1105203859
opoloXAI
2005-01-08 20:04
2005.02.06
Обновление данных в таблице при подключении через TADOTAble.


3-1104332543
Dysan
2004-12-29 18:02
2005.02.06
TCPServer и доступ к dbf





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский