Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Informix [игнор отключен] [закрыт для гостей] / Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса? / 12 сообщений из 12, страница 1 из 1
05.06.2006, 16:07
    #33772704
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
Ситуация:
Есть запрос с набором условий

SELECT *
FROM users
WHERE category IN (x, ..., y)
AND my_sp(id) = 1
AND name LIKE '%LOH:)%'
ORDER BY name;

есть индексы по:
name
category

По планам для IDS 7.31 и для 9.4 видно, что оптимизатор использует индекс по name и фильтр по category IN (x, ..., y) AND my_sp(id) = 1
НО:
IDS 7.31 в последовательности category IN (x, ..., y) AND my_sp(id) = 1
а IDS 9.4: в последовательности my_sp(id) = 1 AND category IN (x, ..., y)
Как вы сами понимаете, в такой ситуации эффект очень сильно зависит от "тяжеловесности" ХП my_sp. Попытки применять полную скобочную запись для управления порядком применения условий фильтра никакого эффекта не возымели - план запроса остался прежним. Приёмы типа "дублирование условия category IN (x, ..., y)" для "повышения важности условия" тоже ни к чему не привели. В общем, не знает ли кто, как можно "заставить" IDS 9.4 применять в данном случае условие my_sp(id) = 1 в ПОСЛЕДНЮЮ очередь?
...
Рейтинг: 0 / 0
05.06.2006, 19:06
    #33773280
Выбегалло
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
С update statistics игрались ?
optimizer hints пробовали ?

В таком вот аксепте
...
Рейтинг: 0 / 0
06.06.2006, 19:24
    #33776027
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
ВыбегаллоС update statistics игрались ?
optimizer hints пробовали ?

Игрались. Пробовали. Добились следующего

подключили индексы по category
НО
IDS 7.31 Filters в последовательности name name LIKE '%LOH:)%' AND my_sp(id) = 1
а IDS 9.4: Filters в последовательности my_sp(id) = 1 AND name LIKE '%LOH:)%'

Как ему объяснить, что вызов ХП my_sp(id) более "тяжеловесный", чем name LIKE '%LOH:)%' я так и не нашёл (тем более в optimizer hint) :(
...
Рейтинг: 0 / 0
06.06.2006, 20:48
    #33776130
Выбегалло
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
Хотелось бы увидеть схемы таблиц и текст процедуры.

В таком вот аксепте
...
Рейтинг: 0 / 0
07.06.2006, 14:53
    #33777944
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
-- drop procedure users;
CREATE TABLE "informix".users(
    id SERIAL
  , name NVARCHAR( 80 )
  , category INT
)

ALTER TABLE users
  ADD CONSTRAINT
    PRIMARY KEY(id)
    CONSTRAINT "informix".pk_users;

CREATE INDEX "informix".idx_users_name
  ON users(name);
  
CREATE INDEX "informix".idx_users_category
  ON users(category);

--drop procedure users_fill;
CREATE PROCEDURE "informix".users_fill(
) 
  
  DEFINE i INT;
  
  FOR i =  1  TO  10000 
     INSERT INTO users(name, category)
       VALUES (i, i /  20 );
  END FOR;
  
   
END PROCEDURE;

EXECUTE PROCEDURE users_fill();
 
-- DROP PROCEDURE user_permissions;

CREATE PROCEDURE "informix".user_permissions(
  p_user_id INT
) RETURNING
  SMALLINT
  ;
  DEFINE i INT;
  
  FOR i =  1  TO  10000 
  
  END FOR;
  RETURN  1 ;
  
END PROCEDURE;

UPDATE STATISTICS HIGH
  FOR TABLE users;

SELECT {+EXPLAIN} *
  FROM users
    WHERE category IN ( 1 ,  2 ,  3 )
      AND name LIKE '%LOH%' 
      AND user_permissions(id) =  1 ; 

SELECT {+EXPLAIN} *
  FROM users
    WHERE category IN ( 1 ,  2 ,  3 )
      AND user_permissions(id) =  1  
      AND name LIKE '%LOH%';  

SELECT {+EXPLAIN} *
  FROM users
    WHERE category IN ( 1 ,  2 ,  3 )
      AND name LIKE '%LOH%';

QUERY:
------
SELECT {+EXPLAIN} *
FROM users
WHERE category IN (1, 2, 3)
AND name LIKE '%LOH%'
AND user_permissions(id) = 1;

DIRECTIVES FOLLOWED:
EXPLAIN
DIRECTIVES NOT FOLLOWED:

Estimated Cost: 4
Estimated # of Rows Returned: 1

1) informix.users: INDEX PATH

Filters: (informix.user_permissions(informix.users.id )= 1 AND informix.users.name LIKE '%LOH%' )

(1) Index Keys: category (Serial, fragments: ALL)
Lower Index Filter: informix.users.category = 1

(2) Index Keys: category (Serial, fragments: ALL)
Lower Index Filter: informix.users.category = 2

(3) Index Keys: category (Serial, fragments: ALL)
Lower Index Filter: informix.users.category = 3

UDRs in query:
--------------
UDR id : 5354
UDR name: user_permissions

QUERY:
------
SELECT {+EXPLAIN} *
FROM users
WHERE category IN (1, 2, 3)
AND user_permissions(id) = 1
AND name LIKE '%LOH%';

DIRECTIVES FOLLOWED:
EXPLAIN
DIRECTIVES NOT FOLLOWED:

Estimated Cost: 4
Estimated # of Rows Returned: 1

1) informix.users: INDEX PATH

Filters: (informix.user_permissions(informix.users.id )= 1 AND informix.users.name LIKE '%LOH%' )

(1) Index Keys: category (Serial, fragments: ALL)
Lower Index Filter: informix.users.category = 1

(2) Index Keys: category (Serial, fragments: ALL)
Lower Index Filter: informix.users.category = 2

(3) Index Keys: category (Serial, fragments: ALL)
Lower Index Filter: informix.users.category = 3

UDRs in query:
--------------
UDR id : 5354
UDR name: user_permissions

QUERY:
------
SELECT {+EXPLAIN} *
FROM users
WHERE category IN (1, 2, 3)
AND name LIKE '%LOH%';

DIRECTIVES FOLLOWED:
EXPLAIN
DIRECTIVES NOT FOLLOWED:

Estimated Cost: 4
Estimated # of Rows Returned: 12

1) informix.users: INDEX PATH

Filters: informix.users.name LIKE '%LOH%'

(1) Index Keys: category (Serial, fragments: ALL)
Lower Index Filter: informix.users.category = 1

(2) Index Keys: category (Serial, fragments: ALL)
Lower Index Filter: informix.users.category = 2

(3) Index Keys: category (Serial, fragments: ALL)
Lower Index Filter: informix.users.category = 3
...
Рейтинг: 0 / 0
07.06.2006, 14:56
    #33777950
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
Да забыл добавить, что время работы первых двух запросов около секунды, а последний - что называется "мгновенно"
...
Рейтинг: 0 / 0
19.06.2006, 21:55
    #33801211
Выбегалло
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
http://publib.boulder.ibm.com/epubs/html/29920280.html

Bug 175113, fixed in 9.40.UC8 OPTIMIZER CHOOSES SEQUENTIAL OR INDEX SCAN DEPENDING ON THE JOIN ORDER OF TABLES

не исключено, что ваша проблема - из того же разряда.

В таком вот аксепте
...
Рейтинг: 0 / 0
21.06.2006, 12:15
    #33805006
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
Выбегалло http://publib.boulder.ibm.com/epubs/html/29920280.html

Bug 175113, fixed in 9.40.UC8 OPTIMIZER CHOOSES SEQUENTIAL OR INDEX SCAN DEPENDING ON THE JOIN ORDER OF TABLES

не исключено, что ваша проблема - из того же разряда.

В таком вот аксепте
Виноват - не уточнил сразу: ситуация как раз на 9.40.UC8 :(
А для него я там же нашёл "Known issues":

175426
ONLINE - SQOPTIM
LEFT OUTER JOIN PERFORMS SEQUENTIAL SCANS INSTEAD OF INDEX SCAN
...
Рейтинг: 0 / 0
21.06.2006, 12:56
    #33805221
Журавлев Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
АнатоЛой...
175426
ONLINE - SQOPTIM
LEFT OUTER JOIN PERFORMS SEQUENTIAL SCANS INSTEAD OF INDEX SCANЭто точно не то, и вообще я не думаю что это баг, возможно просто `in` слегка потяжелел по сравнению с `=`, а тяжесть функции для оптимизатора наверно равна 0.

Я бы попробовал изменить AND my_sp(id) = 1
AND my_sp(id) - 1 = 0 или на
AND my_sp(id) in (1) или на
AND my_sp(id)/2 between 0,49999 and 0,50001
...
Рейтинг: 0 / 0
21.06.2006, 16:29
    #33806259
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
Журавлев ДенисЭто точно не то, и вообще я не думаю что это баг


УПС...
С \'known issues\' я ошибся веткой - я полагал, что речь идёт о не менее актуальном для меня вопросе:
Оптимизация view с OUTER в IDS 9.4UC8

Журавлев Денис
, возможно просто `in` слегка потяжелел по сравнению с `=`, а тяжесть функции для оптимизатора наверно равна 0.
Я бы попробовал изменить AND my_sp(id) = 1
AND my_sp(id) - 1 = 0 или на
AND my_sp(id) in (1) или на
AND my_sp(id)/2 between 0,49999 and 0,50001

Докладываю:

Код: plaintext
\nSELECT {+EXPLAIN} *\n  FROM users\n    WHERE category IN ( 1 ,  2 ,  3 )\n      AND name LIKE \'%LOH%\' \n      AND user_permissions(id) IN ( 1 );\n
Filters: (informix.user_permissions(informix.users.id )= 1 AND informix.users.name LIKE \'%LOH%\')
-- не помогло - LIKE всё ещё "тяжелее" :(

Код: plaintext
\nSELECT {+EXPLAIN} *\n  FROM users\n    WHERE category IN ( 1 ,  2 ,  3 )\n      AND name LIKE \'%LOH%\' \n      AND user_permissions(id) -  1  =  0 ;\n
Filters: (informix.user_permissions(informix.users.id )= 1 AND informix.users.name LIKE \'%LOH%\')
-- не помогло - LIKE всё ещё "тяжелее" :(

Код: plaintext
\nSELECT {+EXPLAIN} *\n  FROM users\n    WHERE category IN ( 1 ,  2 ,  3 )\n      AND name LIKE \'%LOH%\' \n      AND user_permissions(id)/ 2  BETWEEN  0 . 49  AND  5 . 1 ;\n
Filters: ((informix.users.name LIKE \'%LOH%\' AND informix.user_permissions(informix.users.id )/ 2.0000000000000000 <= 0.51) AND informix.user_permissions(informix.users.id )/ 2.0000000000000000 >= 0.49)
НАРЕШТІ! ПОМОГЛО!


Хотя выражение фильтра в Query Plan не может не огорчать...
ПОХОЖЕ, что IDS на каждую строку, попавшую под условие
Код: plaintext
informix.users.name LIKE \'%LOH%\'
, для проверки BETWEEN запускает ХП 2 раза!

Проверяем. К выше упомянутому тесту добавляем:

Код: plaintext
\nCREATE PROCEDURE "informix".clear_counter(\n)\n\n  DEFINE GLOBAL G_user_permissions_calls INT DEFAULT  0 ;\n\n  LET G_user_permissions_calls =  0 ;\n\nEND PROCEDURE; \n\nDROP PROCEDURE user_permissions;\n\nCREATE PROCEDURE "informix".user_permissions(\n   p_user_id INT\n , p_max_cnt INT -- ругаться при вызове больше p_max_cnt раз!\n) RETURNING\n  SMALLINT\n  ;\n  DEFINE i INT;\n\n  DEFINE GLOBAL G_user_permissions_calls INT DEFAULT  0 ;\n\n  LET G_user_permissions_calls = G_user_permissions_calls +  1 ;\n  IF G_user_permissions_calls > p_max_cnt THEN\n    RAISE EXCEPTION - 746 ,  0 , \'2 раза - это 2 раза! (с) Не Я\';\n  END IF; \n  \n  FOR i =  1  TO  10000 \n  \n  END FOR;\n  RETURN  1 ;\n  \nEND PROCEDURE;\n
Добавляем ОДНУ строку, которую должен найти запрос

Код: plaintext
\nINSERT INTO users(name, category)\n       VALUES (\'таки кто-то LOH\',  2 );\n\n

и проверяем доГАДку

Код: plaintext
\nEXECUTE PROCEDURE "informix".clear_counter();\n\nSELECT {+EXPLAIN} *\n  FROM users\n    WHERE category IN ( 1 ,  2 ,  3 )\n      AND name LIKE \'%LOH%\' \n      AND user_permissions(id,  1 )/ 2  BETWEEN  0 . 49  AND  5 . 1 ;\n

В результате получаем ошибку - подтверждение факта, что ХП вызвана 2 раза :(

проверяем ещё раз:

Код: plaintext
\nEXECUTE PROCEDURE "informix".clear_counter();\n\nSELECT {+EXPLAIN} *\n  FROM users\n    WHERE category IN ( 1 ,  2 ,  3 )\n      AND name LIKE \'%LOH%\' \n      AND user_permissions(id,  2 )/ 2  BETWEEN  0 . 49  AND  5 . 1 ;\n

Ошибки нет - найдена одна строка, ХП вызвана РОВНО 2 раза...

П.С.:
"И с ребятами как-то нехорошо получилось..." (с) анек
...
Рейтинг: 0 / 0
21.06.2006, 16:43
    #33806307
Журавлев Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
АнатоЛой...
Ошибки нет - найдена одна строка, ХП вызвана РОВНО 2 раза...

П.С.:
"И с ребятами как-то нехорошо получилось..." (с) анекЧестно говоря я разбираюсь в этом как свинья в апельсинах и буков опять-же много, НО я слыхал что процедуры можно пометить DETERMINISTIC, иначе откудаж он узнает что вызывать надо один раз? Или нет?
...
Рейтинг: 0 / 0
21.06.2006, 20:08
    #33806938
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса?
Журавлев Денис АнатоЛой...
Ошибки нет - найдена одна строка, ХП вызвана РОВНО 2 раза...

П.С.:
"И с ребятами как-то нехорошо получилось..." (с) анекЧестно говоря я разбираюсь в этом как свинья в апельсинах и буков опять-же много, НО я слыхал что процедуры можно пометить DETERMINISTIC, иначе откудаж он узнает что вызывать надо один раз? Или нет?

Да, с буквами тоже "нехорошо получилось" :)
Вкратце смысл следующий: "Если написано <expr> BETWEEN <a> AND <b>", зачем значение <expr> 2 раза вычислять?!
В доке по IDS 7, IDS 9 волшебного слова "DETERMINISTIC" не нашёл. НО: google сказал "ищи VARIANT". Штука сия появилась только в 9-ке - а я пока недостаточно силён в нюансах 9-ки :(.

Результаты - те же (Informix выполняет ХП 2 РАЗА), независимо от того, как создана user_permissions, с

Код: plaintext
1.
  WITH (NOT VARIANT)

или с

Код: plaintext
1.
WITH (VARIANT)

:(
...
Рейтинг: 0 / 0
Форумы / Informix [игнор отключен] [закрыт для гостей] / Как IDS 7.31 и 9.4 определяют порядок применения фильтров при оптимизации запроса? / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]