Страница 1 из 2

Ограничение времени выполнения запроса

Добавлено: 01 июн 2006, 14:41
pticelov
Существует ли у файрбирд (1.5.2) возможность ограничения времени выполнения запроса? Я не нашел нормального способа прервать запрос (только выборка данных, не обновление), если его выполнение заняло неадекватно большоен время.

Я знаю про то, что правильное решение - это не делать непредсказуемых запросов, строить индексы (они есть), обновлять статистику (она обвновляется), поставить вторую версию FB, который получше относится к сложным запросам (не могу сделать быстро) и т.д., но очень хочется иметь средство экстренного прерывания запроса. Работаю через ODBC.

Добавлено: 01 июн 2006, 14:47
kdv
в Firebird - пока нет. Кстати, IB 7.x тоже не всякие запросы может терминировать, как выяснилось.
Я знаю про то, что правильное решение - это не делать непредсказуемых запросов, строить индексы...
вот и нет. для отчетных запросов самое правильное - построение промежуточных агрегатов. То есть, чтобы в системе просто не существовало запросов, которые могут выполняться, скажем, больше 3-5 минут (абстрактно).

Добавлено: 01 июн 2006, 14:48
Dimitry Sibiryakov
Полный облом по всем пунктам.

Добавлено: 01 июн 2006, 15:13
pticelov
Да уж ... Ничего не скажешь - обломали.

Тогда попрошу помощи у зала. На чем зависаем?

таблица 1:
первичный ключ1 integer,
значение11, значение12, значение13 - integer

таблица 2:
первичный ключ2 integer,
значение21, значение22, значение23 - integer

таблица 12
пары ключ1, ключ2

(на самом деле это таблица людей, адресов и связей, причем имена, названия улиц и городов - словарные значения)

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

(значение12=123 or значение13=123) and значение11=456

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

Имеются независимые индексы по каждому из полей всех трех таблиц и объединенный индекс по обоим полям таблицы связей

Все это работает отлично и быстро, до ... неудачного расположения звезд на небе. На каком-то сочетании значений запрос, который работал до того быстро, начинает срашно тормозить (десятки секунд). Смена значений меняет план запроса (меняютися местами таблица1 и 2) и все начинает лелать. Однако непохоже, что дело в неудачном плане - в любом случае мы имеем поиск по индексам, а не natural.


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

в зависимости от количества ключевых слов в поиске строятся запросы типа

select kw1.link from keywords kw1,keywords kw2,keywords kw3 where kw1.link=kw2.link and kw1.link=kw3.link and kw1.word=123 and kw2.word=234 and kw3.word=456

тоже работает - супер, но иногда тормозит!

Добавлено: 01 июн 2006, 15:51
Merlin
pticelov писал(а): Имеются независимые индексы по каждому из полей всех трех таблиц
А ты их статистику смотрел?
pticelov писал(а): Смена значений меняет план запроса (меняютися местами таблица1 и 2) и все начинает лелать. Однако непохоже, что дело в неудачном плане - в любом случае мы имеем поиск по индексам, а не natural.
Именно в нём. а) индексный поиск не всегда лучше натурального б) а ты статистику используемых в том и другом случае индексов смотрел?
В общем прибей порядок таблиц гвоздиком. Лучше через +0, не получится - явным планом. А ещё лучше посмотреть статистику индексов и плохие перебить к едрене фене, может всё само и устаканится.

Добавлено: 01 июн 2006, 16:58
pticelov
Merlin писал(а):
pticelov писал(а): Имеются независимые индексы по каждому из полей всех трех таблиц
А ты их статистику смотрел?
Смотрел, пересобирал. Вроде бы ничего ужасного.
Merlin писал(а):
pticelov писал(а): Смена значений меняет план запроса (меняютися местами таблица1 и 2) и все начинает лелать. Однако непохоже, что дело в неудачном плане - в любом случае мы имеем поиск по индексам, а не natural.
Именно в нём. а) индексный поиск не всегда лучше натурального б) а ты статистику используемых в том и другом случае индексов смотрел?
В общем прибей порядок таблиц гвоздиком. Лучше через +0, не получится - явным планом. А ещё лучше посмотреть статистику индексов и плохие перебить к едрене фене, может всё само и устаканится.
Там табличка на десятки миллионов записей. Какой-такой натурал :) Когда не глючит, оба типа запросов просто летают - время выполнения - десятки-сотни миллисекунд. Как сойдет с ума - десятки секунд. пару раз вообще уходил в ступор - 10 минут 100% загрузки процессора файрбирдом, прибил нафиг птицу.

Перебить - это set statistics?

+0 - это что? Что-то я такого не встречал в документации. Сейчас окажетс ябанальность очевиднаяч :)

Добавлено: 01 июн 2006, 17:01
pticelov
Кстати, в каком случае стоит отказаться от неуникальных индексов? Что-то меня смущает один из них (город), там количество значений (на десятки миллинов записей) очень ограничено (сотни, в лучшем случае - тысячи), причем, как и положено, на пару-тройку "главных" значений приходится подавляющее число записей.

Добавлено: 01 июн 2006, 17:47
kdv
статистику чем смотрел, IBAnalyst-ом?
Когда не глючит
никогда не глючит. просто план запроса меняется так, что ....

Добавлено: 01 июн 2006, 19:41
pticelov
Понятно, что план запроса меняется. Но непонятно, откуда вдруг тормоза, если таблицы этаи абсолютно равнозанчны.

Статистику смотрел и обновлял аналистом. Есть индексы с большим количеством дупов, но они как раз в этом безобразии не участвовали

Добавлено: 01 июн 2006, 21:28
kdv
откуда вдруг тормоза, если таблицы этабсолютно равнозначны.
здрасьте, если запрос другой и ПЛАН запроса другой, то производительность может отличаться на порядки.

Добавлено: 01 июн 2006, 22:58
pticelov
Я наверное туплю.

есть запрос такой:

select ... from tbl1,tnl2,tbl21 where tbl1.link=tbl21.key1 and tbl2.link=tbl21.key2 and tbl1.val1=123 and tbl2.val2=456

есть индексы по всем упомянутым полям, у tbl21 - еще и индекс по паре полей (key1,key2)

почему при смене плана на симметричный начинаются тормоза - мне непонятно.


А что такое +0?

Добавлено: 01 июн 2006, 23:08
Merlin
Потому что размеры таблиц или даже просто количества записей, подпадающих под условия объединения, разные. И какую перебирать первой и по какому индексу - важно. А +0 - это обыгрывание того, что индекс к выражению не применяется. Например, напишешь tbl1.link=tbl21.key1+0 и индекс по key1 на tbl21 использоваться не будет, будет использоваться индекс по link на tbl1, как бы ты ни крутил параметры. То есть, этим можно управлять последовательностью перебора таблиц и не давать оптимизатору пытаться пользовать неподходящий для данного конкретного запроса индекс, хотя для другого запроса этот индекс хорош.

Добавлено: 07 июн 2006, 00:21
pticelov
Я это понимаю, но это не объясняет уход сервера "в себя" на 20 минут на запросе типа
select ... from tbl1,tbl2,tbl21 where tbl1.ke1=... and tbl1.key2=... and tbl1.link=tbl21.key1 and tbl2.link=tbl21.key2 and tbl2.key5=...

"хорошее выполнеине" - доли секунды

"плохое" - десятки секунд.

Но улет на 20 минут я не могу объяснить инкак :( Вот сейчас занимается чем-тос воим уже больше 20 минут. 100% загрузка процессора.

Добавлено: 07 июн 2006, 09:40
kdv
"хорошее выполнеине" - доли секунды
не надо писать ерунду. Скорость выполнения запроса зависит от методов доступа, используемых сервером в конкретном случае. А методы доступа выбираются по типу запроса - сортировка, группировка, поиск по индексу, наличие индексов, и т.п.
Если ты запросом задаешь серверу отсортировать миллионов 5 записей, то он никак это за "доли секунды" выполнить не может.
Но улет на 20 минут я не могу объяснить инкак
это ты так запросы пишешь.

Судя по всему, раз ты план не привел и не понял объяснения Merlin-а, тебе пока стоит пенять именно на себя, а не на сервер.

Добавлено: 08 июн 2006, 01:58
pticelov
А может не наезжать, а прочитать, что тебе пишут. Я же написал, что за запрос и метод доступа. Поиск всегда по индексу, сортировка отсуствует. Именно поэтому нормальное время выполнения - доли секунды, при некоторых значениях - секунды (тут как раз "объяснение Мерлина"), иногда - десятки минут. На запросе таком:

select person.link,person.fname,person.pname,person.sname,person.birthday from person_1 person,address_1 address,person2addr_1 p2a where person.fname=450 and person.pname=344 and person.sname=71921 and person.birthday between 18800101 and 19671231 and p2a.person=person.link and p2a.addr=address.link and address.street in (39346)

план

PLAN JOIN (ADDRESS INDEX (ADDRESS_STREET_1),PERSON INDEX (PERSON1_1,PERSON_BIRTHDAY_1),P2A INDEX (PERSON2ADDR_1_1))

индексы:
person1_1 - по полям fname,sname,pname
PERSON2ADDR_1_1 - по полям addr,person
остальные - по одиночным полям

in с одним значением - поскольку запрос генерится автоматом и утт может быть несколько значений.

десяток миллионов записей в каждой таблице, инедксы по всем полям. На магических значениях - висим полчаса, 100% загрузка.

Добавлено: 08 июн 2006, 03:45
CyberMax
1. Джойн через where - дурной тон.
2. Когда строишь запрос, сразу форматируй его. Это облегчит его понимание и тебе, и другим.
2. Попробуй вот так задать запрос:

select
person.link,
person.fname,
person.pname,
person.sname,
person.birthday
from
person_1 person
left join person2addr_1 p2a on person.link = p2a.person
left join address_1 address on p2a.addr = address.link
where
(person.fname=450)
and (person.pname=344)
and (person.sname=71921)
and (person.birthday between 18800101 and 19671231)
and (address.street in (39346))

Все условия взяты в скобки. Серверу в некоторых ситуациях все равно, а человеку понятнее. Особенно настораживает использование between без скобок.
4. Напиши, какой стал план.

Добавлено: 08 июн 2006, 05:20
dimitr
покажи статистику (из gstat-а по всем индексам плана). Ставлю поллитру на то, что у тебя в одном из ключей сильно неравномерное распределение.

Добавлено: 08 июн 2006, 10:13
pticelov
Я не могу сразу форматировать запрос из-за того, что запросы у меня строятс яавтоматом и могут быть разными, в зависимости от входных значений. Этот еще очень хороший получился. Но зависает.

Попробую чуть позже и статистику возьму

Но что важно - виснет на строго определенной подборке входных значений. Перестройка статистики всех индексов, кстати, помогает - ранее виснувшие запросы начинабт работать. Но проявляются новые "висуны". Я на трогаю статистику пока специально, чтобы иметь нормальную воспроизводимость поблемы.

Добавлено: 08 июн 2006, 10:20
CyberMax
pticelov писал(а):Я не могу сразу форматировать запрос из-за того, что запросы у меня строятс яавтоматом и могут быть разными, в зависимости от входных значений.
У меня тоже нет ни одного жестко написанного запроса. Всю работу по формированию вида запросов делают соответствующие методы. Что мешает тебе вместо, например, 'select ' + 'person.link' написать 'select'#13#10 + SpaceTab + 'person.link'?

Добавлено: 10 июн 2006, 17:57
pticelov
2 cybermax

переделка запроса с явным указанием join изменила план и исправила время выполнения (работает мгновенно)

План

PLAN JOIN (JOIN (PERSON INDEX (PERSON1_1,PERSON_BIRTHDAY_1),P2A INDEX (PERSON2ADDR_PERSON_1)),ADDRESS INDEX (ADDRESS_00_1))