Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.04.21;
Скачать: CL | DM;

Вниз

SELECT * FROM TABLE T WHERE (T.id = :param) OR (:param = -1)   Найти похожие ветки 

 
Lexer ©   (2010-11-03 11:16) [0]

Добрый день.
На досуге начал оптимизировать свои запросы, и столкнулся с неприятным поведением Firebird :(

Задача передать параметр в запрос, и если параметр определенного значения, скажем -1 то выбирать все строки.
Например:
SELECT *
FROM WARE W
WHERE ((W.id_ware = :param) OR (:param = -1))
Но при этом индекс по id_ware как оказалось не используется :( Вобщем нашел причину тормозов в своих процедурах. Это только маленький пример, запросы с подобными параметрами использую в в процедурах с большим телом в for select
Нашел пока 2 варианта решения, но все они кривые:
1. разбить на два запроса проверив сначала параметр, но при этом надо будет и дублировать и вычисления для каждого запроса :(
т.е
2. в данной процедуре сначала сформировать в переменную запрос в зависимости от параметра и запихнуть его в execute statement, при этом не придется дублировать вычисления, но выглядеть это будет криво.
3. создать для запроса отдельную процедуру и в проуедуре вычислений доставть данные из неё, но данные вариант имеет два минуса: лишняя процедура, дублирование во второй процедуре тела запроса.
Кто-нибудь сталкивался с подобными задачами? Помогите, пожалуста найти более прямой вариант. Если надо могу описать задачу подробнее.


 
Sergey13 ©   (2010-11-03 12:07) [1]

Как вариант
SELECT *
FROM WARE W
WHERE W.id_ware between :param and :param1

если надо все то от -1 до бесконечности, если одно значения - параметры равны


 
Lexer ©   (2010-11-03 12:25) [2]

Sergey13, Гениально! И главное просто и красиво! Респект и уважуха!!!
Набросил примерчик всё работает отлично

CREATE PROCEDURE SP_TESTIK (param INTEGER)
AS
 DECLARE VARIABLE MaxInt INTEGER;
 DECLARE VARIABLE param2 INTEGER;
BEGIN
 MaxInt = 2147483647; -- (2^32)-1
 IF (param IS NULL) THEN param = -1000;

 IF (param = -1000) THEN param2 = MaxInt; ELSE param2 = param;
 FOR
   SELECT W.id_ware
     FROM WARE W
    WHERE W.id_ware BETWEEN :param AND :param2
     INTO :id_ware
 DO
   BEGIN
     -- тыры пыры
     -- спасибо Сергею :)
   END
END


 
sniknik ©   (2010-11-03 12:58) [3]

> Но при этом индекс по id_ware как оказалось не используется
причина может быть в одноименных параметрах... только в BDE насколько помню так было можно. в ADO же (и др.)  одноименные не определяются по имени оба, а только один, т.е. может не использоваться id_ware а может и не сработать сравнение с -1, смотря как парсер определяющий параметры работает.

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


 
Lexer ©   (2010-11-03 13:29) [4]

sniknik, с одноименнными параметрами действительно были проблемы когда работал с BDE, использовал отдельный "need_all=(1,0)", но те времена прошли

здесь как оказалось проблема в самой СУБД
например запросы
SELECT * FROM TABLE T WHERE T.id = :param - индекс используется
SELECT * FROM TABLE T WHERE (T.id = :param) OR (1=0) - индекс не используется, идет чтение всех строк :(
SELECT * FROM TABLE T WHERE 1=0 - и в этом запросе индекс не используется, идет чтение всех строк, хотя по условию можно было бы файрбёрду догадаться что таблицу то и проверять ненадо


 
stas ©   (2010-11-03 14:35) [5]

sniknik ©   (03.11.10 12:58) [3]
Да это вопрос СУБД.MSSQL так же работает.


 
Кщд   (2010-11-08 07:38) [6]

>Lexer ©   (03.11.10 11:16)
>На досуге начал оптимизировать свои запросы, и столкнулся с неприятным >поведением Firebird :(
вполне предсказуемое поведение оптимизатора

если переписать через union?



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

Текущий архив: 2013.04.21;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.008 c
15-1355987109
Toretto
2012-12-20 11:05
2013.04.21
присвоение результата фанции


15-1356108128
alexdn
2012-12-21 20:42
2013.04.21
Где ещё можно продать программу?


2-1349962404
Wadimka
2012-10-11 17:33
2013.04.21
Как изменить имя текущего пользователя Windows?


4-1264592623
Владислав
2010-01-27 14:43
2013.04.21
Входит ли пользователь в группу AD.


2-1349939341
Grimm375
2012-10-11 11:09
2013.04.21
if else if несколькольких дефайнов