Время выполнения запроса

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

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

Re: Время выполнения запроса

Сообщение hvlad » 27 фев 2009, 12:11

pticelov писал(а):А что значит "сканируется" в пунктах "а" и "б"?
Насколько я понимаю, в пункте а - это не сканирование, а поиск - просмотр трех страниц (в соответствии с глубиной индекса) и получение номеров записей, подпадающих под условие, складывание их в какую-то структуру (не важно какую).
Да, там поиск по ключу, относительно дешёвый.
pticelov писал(а):А на пункте "б" возможно 2 варианта:
- полное сканирование второго индекса от начала к концу с проверкой на то, попадает ли запись номер X в список с пункта "а", если попадает - вывод
Именно это я и написал
pticelov писал(а):- поиск записей с номерами из пункта "а" во втором индексе, сохранение позиций в индексе и сортировка списка, с последующим выводом
По какому критерию поиск во втором индексе ?
pticelov писал(а):Я почему-то предполагал второй вариант, но если там первый вариант - то это и впрямь жопа :(
Учимся сначала думать, а потом искать жопы.

pticelov
Сообщения: 95
Зарегистрирован: 28 дек 2005, 22:52

Re: Время выполнения запроса

Сообщение pticelov » 28 фев 2009, 04:03

hvlad писал(а):
pticelov писал(а):А на пункте "б" возможно 2 варианта:
- полное сканирование второго индекса от начала к концу с проверкой на то, попадает ли запись номер X в список с пункта "а", если попадает - вывод
Именно это я и написал
Спасибо, переспросить никогда не вредно.

В общем, это упростило понимание проблемы. Напрягши мозг, догадался, что индекс должен сканироваться не всегда полностью - при наличии ограничения значения поля, по которому ведется сортировка, это же ограничение влияет и на диапазон сканирования индекса для сортировки. Проверил догадку на практике, добавив разумные ограничения в этот самый id, получил резкое ускорение ранее тормозившего запроса, который не хотелось превращать в +0. Почти реалтайм :)

В процессе эксперимента решил проверить еще идею о том, что время первого fetch при сортировке определяется расстоянием от начала индекса до первой попавшей в битмап записи, но столкнулся с парадоксом: выбрав такой CID, чтобы все записи с ним заведомо находились в самом конце истории (в начале обратно сортированного индекса), и сделав запрос
select * from incalls where cid='2290000' order by id desc

я получил те же волшебные 200 мс на первом fetch, что никак не вписывается в сложившееся в голове понимание ситуации

в статистике
Preparing query: SELECT * from incalls where cid='2290000' order by id desc
Prepare time: 00:00:00.
PLAN (INCALLS ORDER INCALLS_ID_D INDEX (INCID))

Executing...
Done.
1506 fetches, 0 marks, 0 reads, 0 writes.
0 inserts, 0 updates, 0 deletes, 19 index, 0 seq.
Delta memory: 40 bytes.
Execute time: 00:00:01.
Script execution finished.
pticelov писал(а):- поиск записей с номерами из пункта "а" во втором индексе, сохранение позиций в индексе и сортировка списка, с последующим выводом
По какому критерию поиск во втором индексе ?
Вопрос некорректный :) Потому что если спросить "как это сделать в firebird" мой ответ будет "не знаю, я не ковырял", а "как это сделать теоретически" - придумывается легко, но пользы нет. Я просто пытался уточнить, чтобы однозначно понимать, как работает, а не программированию поучить.

А из разряда вполне очевидных идей есть такая мысль к разработчику: а почему ФБ не пытается после построения битмапа оценить количество записей в выборке и при небольшом их числе (относительно размера индекса) просто отключить использование индекса в сортировке? Вроде бы идея очевидная.

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

Re: Время выполнения запроса

Сообщение hvlad » 28 фев 2009, 13:32

pticelov писал(а):В процессе эксперимента решил проверить еще идею о том, что время первого fetch при сортировке определяется расстоянием от начала индекса до первой попавшей в битмап записи, но столкнулся с парадоксом: выбрав такой CID, чтобы все записи с ним заведомо находились в самом конце истории (в начале обратно сортированного индекса), и сделав запрос
select * from incalls where cid='2290000' order by id desc
Т.е. для cid='2290000' есть ID, близкий к максимальному ?
pticelov писал(а):я получил те же волшебные 200 мс на первом fetch, что никак не вписывается в сложившееся в голове понимание ситуации

в статистике
Preparing query: SELECT * from incalls where cid='2290000' order by id desc
Prepare time: 00:00:00.
PLAN (INCALLS ORDER INCALLS_ID_D INDEX (INCID))

Executing...
Done.
1506 fetches, 0 marks, 0 reads, 0 writes.
0 inserts, 0 updates, 0 deletes, 19 index, 0 seq.
1506 фетчей чётко указывает на долгий скан индекса.
pticelov писал(а):
hvlad писал(а):
pticelov писал(а):- поиск записей с номерами из пункта "а" во втором индексе, сохранение позиций в индексе и сортировка списка, с последующим выводом
По какому критерию поиск во втором индексе ?
Вопрос некорректный :) Потому что если спросить "как это сделать в firebird" мой ответ будет "не знаю, я не ковырял", а "как это сделать теоретически" - придумывается легко, но пользы нет
Вопрос самый что ни на есть корректный, просто нужно подумать немного.
А ответ будет одинаковый для всех СУБД с индексами - ключи в индексе упорядочены прежде всего по значению ключа, а не номеру записи.
Давай своё "придумывается легко", посмотрим ;)
pticelov писал(а):А из разряда вполне очевидных идей есть такая мысль к разработчику: а почему ФБ не пытается после построения битмапа оценить количество записей в выборке и при небольшом их числе (относительно размера индекса) просто отключить использование индекса в сортировке? Вроде бы идея очевидная.
НЕТ НИКАКОЙ СОРТИРОВКИ в плане с ORDER, когда ты это поймёшь ?!
План выполнения запроса строится на этапе prepare.
И динамическое изменение плана запроса (во время выполнения) не так просто, как кажется.
И я не знаю ни одной СУБД, в которой это было бы реализовано.

pticelov
Сообщения: 95
Зарегистрирован: 28 дек 2005, 22:52

Re: Время выполнения запроса

Сообщение pticelov » 28 фев 2009, 16:15

hvlad писал(а):Т.е. для cid='2290000' есть ID, близкий к максимальному ?
Да, причем я так подобрал, чтобы все имеющиеся записи имели ID близкий к максимуму. Максимальный ID=1690161, а записи с CID 2290000 имеют ID=1690115, 1690112, 1690110
1506 фетчей чётко указывает на долгий скан индекса.
Я на это тоже обратил внимание. Хотя по смыслу сканирование индекса дожно было прекратиться после того, как все 3 записи выведены, а он все отсканировал. В моей голове это не укладывается.

Вопрос самый что ни на есть корректный, просто нужно подумать немного.
А ответ будет одинаковый для всех СУБД с индексами - ключи в индексе упорядочены прежде всего по значению ключа, а не номеру записи.
Давай своё "придумывается легко", посмотрим ;)
Он корерктен в контексте СУБД, про которую известно, что индекс там предназначен только для получения ноемра записи по ключу :) Я же задавал вопрос без такого знания.

Ну а "придумывается легко" - это, например, доп. индекс, для перевода номера записи в порядковый номер при упорядоченном выводе. Дороже по памяти, дороже по добавлению данных, дешевле в случае упорядоченного вывода маленького набора. Но это - теоретизирование.
pticelov писал(а):А из разряда вполне очевидных идей есть такая мысль к разработчику: а почему ФБ не пытается после построения битмапа оценить количество записей в выборке и при небольшом их числе (относительно размера индекса) просто отключить использование индекса в сортировке? Вроде бы идея очевидная.
НЕТ НИКАКОЙ СОРТИРОВКИ в плане с ORDER, когда ты это поймёшь ?!
Я не очень корректно сформулировал свою идею, хвост следует читать как: "отключить использование индекса при упорядоченном выводе и сделать как обычно без индекса - прочитать все записи и отсортировать". То, что упорядоченный вывод по индексу не требует сортировки - я понял уже.
План выполнения запроса строится на этапе prepare.
И динамическое изменение плана запроса (во время выполнения) не так просто, как кажется.
И я не знаю ни одной СУБД, в которой это было бы реализовано.
Ну я не знаю, как устроен ФБ, но это напрашивается. Верю, что внутри есть какие-то проблемы.

В jet'е как-то данная проблема обходится - он не подтормазивает на таких запросах. Отчего я и наступил на граблю со всего размаху при переходе с него на ФБ. Вроде привык с этим жить уже, чутка редизайнил софт, разбив все на 2 коннкшна к БД для предсказуемых и непредсказуемых запросов, чтобы реалтайм часть не тормозилась, случись что. Еще бы с вопросом, который у меня в начале этого комментария разобраться - и все будет хорошо.

Кстати, небольшой вопрос про embedded: у обыного ФБ я мог уоткрыть сколько угодно коннешнов он одного приложения, но если я хочу, чтобы запросы выполнялись параллельно, я должен все открывать по TCP. А что делать с embedded?

Ответить