Форум "DataBase и SQL"
Язык запросов баз даных
ОЧЕНЬ долгое выполнение запроса в Firebirdесть выборки 1) select STORE_DOC_IDRP_CONTRACTOR_METAL - хранимая процедура выполняется 2 секунды, возвращает 7 значений 2) select * from L_STORE_DOC LSD выполняется 2 секунды, возвращает 3821 значений все красиво, все довольны... НО! 3) их симбиоз select * from L_STORE_DOC LSD where LSD.ID in (select STORE_DOC_ID from RP_CONTRACTOR_METAL ('01.01.2007', '01.01.2008')) виснет, ждал около 5 минут, но результата так и не дождался... ЧТО ЗДЕСЬ НЕ ТАК ?
|
|
#1 Mystic © 24.04.07 19:54:54
Нет, все правильно, 3821 * 2 = 7624 секунды = 127 минут ~= 2 часа |
|
если заменить позапрос на его реальные значения -- то все отлично.... т.е. вот такой вариант работает на ура select *В чем же проблема? в подзапросе нельзя использовать хранимую процедуру? Но почему тогда сервер не выдает ошибку, а просто тупо виснет? |
#3 Mystic © 24.04.07 19:57:54
А вот должно отработать быстрее |
|
> #1 Mystic © если бы в подзапросе использовались динамические параметры, то да, а если там статика ('01.01.2007', '01.01.2008') - зачем выполнять подзапрос для каждой строки выборки? Глупый сервер? |
|
#5 Mystic © 24.04.07 19:59:21
> > В чем же проблема? в подзапросе нельзя использовать хранимую > процедуру? Но почему тогда сервер не выдает ошибку, а просто > тупо виснет? Почему виснет? Выполняется |
#6 Mystic © 24.04.07 20:01:15
> Глупый сервер? Да глупый. Откуда он знает, что вернет хранмая процедура? А вдруг там стоит рандом? Или еще какая ерунда? Сервер не анализировал хранимую процедуру на предмет того, всегда ли она будет возвращать один и тот же набор данных или нет, он просто выполнил то, что ты написал. |
|
> #3 Mystic © да, ты прав так отработало вобще за 1 сек. |
|
#8 Mystic © 24.04.07 20:04:35
Хм... чудно... Значит хранимая процедура выполняется 2 секунды, но если ее вставить в запрос, то выполнится быстрее? Хотя может быть кэш и прочая ерунда |
|
> #6 Mystic © гм... насчет рандома как-то не подумал, действительно процедуры бывают "разные" Вобщем, респект. Очередной +1 к твоей репутации |
|
> #8 Mystic © ну, я с секундомером не засекал, но такое сложилось впечатление. Собственно, здесь наверное может зависеть еще от свободной оперативки на момент выполнения запроса и т.п. |
|
#11 Mystic © 24.04.07 20:09:34
Давно я не оптимизировал SQL... Последний раз в результате оптимизации запроса скорость его выполнения уменьшилась с 20 мин до 0.1 сек. |
|
> #11 Mystic © а не подскажешь, можно ли в моем случае указать через план запросов, что подзапрос должен выполнятся только один раз? |
|
#13 Mystic © 24.04.07 22:25:45
Я не подскажу, ибо никогда с ним не работал... Вообще я говорил исходя из общих знаний SQL, а не конкретно Firebird. А... нескромный вопрос... Зачем тебе? |
|
За последний год пришлось вплотную поработать с Firebird, а вот до этой возможности руки дошли только сейчас. Собственно сначала все проектировалось, потом вносились изменения и дополнения... а счас вот приходит время оптимизации. Да и довольно интересная фича этот план запросов, чтоб просто обойти ее стороной. В общих чертах представление есть, но толку от него, если не применять это на практике? |
|
#15 Mystic © 25.04.07 00:26:37
я думаю, что большую часть оптимизации можно сделать просто переписав SQL запрос, типа как этот |
|
> #3 Mystic © вот так замечательно работает а вот так (с left join) тоже траблы начинаются... пишет вот такую интересную мессагу: The cursor identified in the update or delete statement is not positioned on row. No current reccord for fetch operation. |
#17 Mystic © 25.04.07 08:29:37
А если так? select LSD.*
|
|
> #17 Mystic © опа, работает! Вроде не первый год с SQL работаю, а не знал, что так можно сделать. Респект. |
|
#19 Mystic © 25.04.07 19:13:58
Наоборот, вполне логично... В секции FROM разделитель запятая. Т. е. ты делаешь выборку из наборов данных 1) L_STORE_DOC 2) RP_CONTRACTOR_METAL('01.01.2007', '01.01.2008') RPCM left join L_CONTRACTOR_DOC LCD on LCD.ID = LSD.CONTRACTOR_DOC_ID Собственно говоря, слева в левом объединении стоит RP_CONTRACTOR_METAL, а он не может в этом наборе найти недостающие записи, для которых условие LCD.ID = LSD.CONTRACTOR_DOC_ID не выполняется. Или что-то в этом роде, все-таки лучше быть аккуратным. P. S. А как ты +1 ставишь? |
|
> #19 Mystic © та теперь я уже понял, просто раньше у меня было четкое ложное убеждение, что join~ы должны идти обязательно после списка таблиц в разделе from. > P. S. А как ты +1 ставишь? есть такая админская возможность |
|
#21 Mystic © 26.04.07 09:42:05
> #20 Deep © 25.04.07 21:41:29 Тогда напиши на досуге интерпретатор SQL. Или просто задумайся над тем, как интерпретируются вопросы... ИМХО, во многих книгах об этом не пишут, и это есть большой минус. Хоть SQL и декларативный язык, но иногда приходится использовать дао для того, чтобы добиться инмеративности... |
|
> Тогда напиши на досуге интерпретатор SQL. когда-то этим заморачивался Правда писал не с нуля, а брал за основу чужой исходник. С алиасами таблиц и полей много намаялся. В итоге -- не дописал, такими вещами надо заниматься ТОТАЛЬНО(без отрыва на основные проекты), а не ФАКУЛЬТАТИВНО. > во многих книгах об этом не пишут в том-то и дело, что подобного синтаксиса я нигде ранее не встречал - ни в книгах, ни в статьях. Наверное, не те книжки попадались. |
Написать ответ |
|

#3 Mystic