Главная страница
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
9-1194462751
Babooin
2007-11-07 22:12
2013.04.21
DirectX vs OpenGL


15-1352870840
pavel_guzhanov
2012-11-14 09:27
2013.04.21
Выбор планшета


2-1350003007
Вова
2012-10-12 04:50
2013.04.21
база данных на dataSet проблема с сохранением данных


15-1356388018
wl
2012-12-25 02:26
2013.04.21
что подарить кресной на новый год?


2-1349629558
dars73
2012-10-07 21:05
2013.04.21
Проблема с кодировкой