Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2013.04.21;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.46 MB
Время: 0.002 c
15-1355289271
Andy BitOff
2012-12-12 09:14
2013.04.21
Ждем 12.12.12 12:12:12.12


15-1355987109
Toretto
2012-12-20 11:05
2013.04.21
присвоение результата фанции


15-1356121802
Юрий
2012-12-22 00:30
2013.04.21
С днем рождения ! 22 декабря 2012 суббота


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


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





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский