Форум: "Базы";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];
ВнизРезультаты выполнение ХП с индексами и без Найти похожие ветки
← →
yaral © (2006-07-24 14:32) [0]У меня имеется ХП которая делает выборку по 1-й таблице. Когда я ее делал индексов в этой таблице не было, и она правильно работала. Но как только для увиличение быстродействия я добавил индексы, ХП стала возращать не правильные результаты.
От чего подобное может произойти? Может версия сервера с багами? Использую FB 1.5.0.4306.
← →
Sergey13 © (2006-07-24 14:38) [1]2 [0] yaral © (24.07.06 14:32)
> Может версия сервера с багами? Использую FB 1.5.0.4306.
Кто мешает скачать последнюю версию и проверить?
← →
yaral © (2006-07-25 06:34) [2]Проверил, не помогло, не в этом дело. Нашел один индекс, его удаляю, все выполняется правильно, добавляю обратно, выполняется не правильно. Почему это может быть?
← →
Sergey13 © (2006-07-25 08:20) [3]2 [2] yaral © (25.07.06 06:34)
> Почему это может быть?
Я еще кофе не пил, потому гущи нет - гадать не на чем.
← →
yaral © (2006-07-25 08:55) [4]>> Sergey13 © (25.07.06 08:20) [3]
Причем тут кофе? Не сталкивался если с такой ситуацией, то вроде и писать не очем.
Просто оригинально, без индекса работает, с индексом нет, как такое возможно?
← →
Johnmen © (2006-07-25 08:58) [5]
> как такое возможно?
Никак.
← →
yaral © (2006-07-25 09:04) [6]>> Johnmen © (25.07.06 08:58) [5]
Вот и я про тоже, вроде не должно такого быть то! Но есть!
Т.е. Это глюк сервера БД надо пологать?
← →
Sergey13 © (2006-07-25 09:06) [7]> [4] yaral © (25.07.06 08:55)
> Причем тут кофе?
Ты считаешь - это чудо? Я думаю, что у тебя ошибка в программе.
Кто из нас прав - покажет время. 8-)
← →
sniknik © (2006-07-25 09:12) [8]если чегото не может быть, но оно есть, то это точно глюк... того кто его видит... т.к. если его можно описать и повторить у других то это уже будет баг.
← →
Johnmen © (2006-07-25 09:17) [9]В потолке открылся люк - не волнуйтесь, это глюк (с)
← →
atruhin © (2006-07-25 10:37) [10]> Т.е. Это глюк сервера БД надо пологать?
Это глюк процедуры
← →
atruhin © (2006-07-25 10:38) [11]> Причем тут кофе?
Намек чтобы ты процедуру выложил?
← →
yaral © (2006-07-25 11:27) [12]> atruhin © (25.07.06 10:38) [11]
Процедура:
CREATE PROCEDURE BUILD_CONTREE(
IOBJ_ID INTEGER,
ISTATE1 INTEGER,
ISTATE2 INTEGER)
RETURNS (
CONTREE_ID INTEGER,
PARENT_ID INTEGER,
OBJ_ID INTEGER,
RTYPE_ID INTEGER,
LNAME VARCHAR(250),
CODE VARCHAR(5),
ORDERINT INTEGER,
STATE INTEGER)
AS
DECLARE VARIABLE VNOREC_ID INTEGER;
DECLARE VARIABLE VCONTREE_ID INTEGER;
DECLARE VARIABLE VRTYPE_ID INTEGER;
BEGIN
VNOREC_ID=0;
FOR SELECT CONTREE_ID, PARENT_ID, OBJ_ID, RTYPE_ID, LNAME, CODE, ORDERINT, STATE FROM CONTREE
WHERE OBJ_ID=:IOBJ_ID AND (RTYPE_ID=1 OR RTYPE_ID=2 OR RTYPE_ID=3) AND STATE=1
ORDER BY ORDERINT
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO BEGIN
SUSPEND;
VCONTREE_ID = :CONTREE_ID;
VRTYPE_ID = :RTYPE_ID + 3;
IF (NOT EXISTS (SELECT * FROM CONTREE
WHERE PARENT_ID=:CONTREE_ID AND (STATE=:ISTATE1 OR STATE=:ISTATE2)
)) THEN
BEGIN
VNOREC_ID = :VNOREC_ID - 1;
FOR SELECT :VNOREC_ID, :VCONTREE_ID, :OBJ_ID, :VRTYPE_ID, "", "<...>", 1, :STATE FROM ZX
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO SUSPEND;
END
FOR SELECT CONTREE_ID, PARENT_ID, OBJ_ID, RTYPE_ID, LNAME, CODE, ORDERINT, STATE FROM CONTREE
WHERE PARENT_ID=:CONTREE_ID AND (STATE=:ISTATE1 OR STATE=:ISTATE2)
ORDER BY ORDERINT
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO BEGIN
SUSPEND;
IF (NOT EXISTS (SELECT * FROM CONTREE
WHERE PARENT_ID=:CONTREE_ID AND (STATE=:ISTATE1 OR STATE=:ISTATE2)
)) THEN
BEGIN
VCONTREE_ID = :CONTREE_ID;
VNOREC_ID = :VNOREC_ID - 1;
FOR SELECT :VNOREC_ID, :VCONTREE_ID, :OBJ_ID, 7, "", "<...>", 1, :STATE FROM ZX
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO SUSPEND;
END
FOR SELECT CONTREE_ID, PARENT_ID, OBJ_ID, RTYPE_ID, LNAME, CODE, ORDERINT, STATE FROM CONTREE
WHERE PARENT_ID=:CONTREE_ID AND (STATE=:ISTATE1 OR STATE=:ISTATE2)
ORDER BY FMAIN DESC, ORDERINT
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO SUSPEND;
END
END
END
Вызов:
SELECT * FROM BUILD_CONTREE(381, 1, 1)
Без индекса по полю ORDERINT:
План
PLAN (CONTREE INDEX (CONTREE_IDX1))(ZX NATURAL)(CONTREE INDEX (CONTREE_IDX1))(ZX NATURAL)SORT ((CONTREE INDEX (CONTREE_IDX1)))SORT ((CONTREE INDEX (CONTREE_IDX1)))SORT ((CONTREE INDEX (CONTREE_IDX2,CONTREE_IDX3,CONTREE_IDX3,CONTREE_IDX3)))
Адаптированный план
PLAN (CONTREE INDEX (CONTREE_IDX1))(ZX NATURAL)(CONTREE INDEX (CONTREE_IDX1))(ZX NATURAL)SORT ((CONTREE INDEX (CONTREE_IDX1)))SORT ((CONTREE INDEX (CONTREE_IDX1)))SORT ((CONTREE INDEX (CONTREE_IDX2,CONTREE_IDX3,CONTREE_IDX3,CONTREE_IDX3)))
------ Performance info ------
Prepare time = 0ms
Execute time = 100ms
Avg fetch time = 5,88 ms
Current memory = 1 424 752
Max memory = 27 333 076
Memory buffers = 2 048
Reads from disk to cache = 22
Writes from cache to disk = 2
Fetches from cache = 231
С индексом по полю ORDERINT (дает не верные результаты):
План
PLAN (CONTREE INDEX (CONTREE_IDX1))(ZX NATURAL)(CONTREE INDEX (CONTREE_IDX1))(ZX NATURAL)SORT ((CONTREE INDEX (CONTREE_IDX1)))(CONTREE ORDER CONTREE_IDX5)(CONTREE ORDER CONTREE_IDX5)
Адаптированный план
PLAN (CONTREE INDEX (CONTREE_IDX1))(ZX NATURAL)(CONTREE INDEX (CONTREE_IDX1))(ZX NATURAL)SORT ((CONTREE INDEX (CONTREE_IDX1)))(CONTREE ORDER CONTREE_IDX5)(CONTREE ORDER CONTREE_IDX5)
------ Performance info ------
Prepare time = 0ms
Execute time = 50ms
Avg fetch time = 3,85 ms
Current memory = 2 204 040
Max memory = 27 333 076
Memory buffers = 2 048
Reads from disk to cache = 0
Writes from cache to disk = 2
Fetches from cache = 833
← →
Johnmen © (2006-07-25 11:49) [13]Хотелось бы уточнить, что значит "дает не верные результаты"? В чём их "неверность"?
← →
yaral © (2006-07-25 12:00) [14]На выходе получается дерево, с тремя уровнями:
1 - Типы групп (пользователи, функции, зоны), их всегда три.
2 - Сами группы
3 - События
Если в типе групп, нет не одного узла то зозращается пустая запись м именем <...> и отрицательным ид. Также с событиями если их нет.
Так вот, в неправильном варианте, т.е. с индексом, возвращается только первая группа в Типе, а события в ней в полном объеме присутствуют. Т.е. в таблице то они все есть, никуда не делись, я только индекс создал по полю.
Тут же запускаю в режиме трассировки в IB Expert и все записи как и положено вижу. Индекс удаляю, и опять все записи получаю. И на другой машине запускал... тоже самое.
← →
atruhin © (2006-07-25 12:13) [15]Разберись с переменной CONTREE_ID, ты в if присвееваешь ей значение, далее опять используешь и т.д.
← →
yaral © (2006-07-25 12:19) [16]CONTREE_ID - выходным параметром? Да вроде все нормально, как же не присваевая ему ничего запихнуть его в выходной НД?
← →
atruhin © (2006-07-25 12:27) [17]Здесь ты присваеваешь значение VNOREC_ID - 1
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
Следом за этим ты
WHERE PARENT_ID=:CONTREE_ID
Может я не правильно понял логику, но вроде в ней должно быть значение из внешнего цикла. Далее если в if exist ты убедился что записей нет, зачем ты следом делаешь запрос с такими же параметрами.
← →
yaral © (2006-07-25 12:53) [18]> atruhin © (25.07.06 12:27) [17]
Ага действительно странно, что это я так, но я думаю это к делу не относиться т.к. под условиеWHERE PARENT_ID=:CONTREE_ID
c CONTREE_ID<0 все равно ни одна запись не подойдет.
Но исправил на такой вариант, все тоже самое.CREATE PROCEDURE BUILD_CONTREE(
IOBJ_ID INTEGER,
ISTATE1 INTEGER,
ISTATE2 INTEGER)
RETURNS (
CONTREE_ID INTEGER,
PARENT_ID INTEGER,
OBJ_ID INTEGER,
RTYPE_ID INTEGER,
LNAME VARCHAR(250),
CODE VARCHAR(5),
ORDERINT INTEGER,
STATE INTEGER)
AS
DECLARE VARIABLE VNOREC_ID INTEGER;
DECLARE VARIABLE VCONTREE_ID INTEGER;
DECLARE VARIABLE VRTYPE_ID INTEGER;
BEGIN
VNOREC_ID=0;
FOR SELECT CONTREE_ID, PARENT_ID, OBJ_ID, RTYPE_ID, LNAME, CODE, ORDERINT, STATE FROM CONTREE
WHERE OBJ_ID=:IOBJ_ID AND (RTYPE_ID=1 OR RTYPE_ID=2 OR RTYPE_ID=3) AND STATE=1
ORDER BY ORDERINT
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO BEGIN
SUSPEND;
VCONTREE_ID = :CONTREE_ID;
VRTYPE_ID = :RTYPE_ID + 3;
IF (NOT EXISTS (SELECT * FROM CONTREE
WHERE PARENT_ID=:CONTREE_ID AND (STATE=:ISTATE1 OR STATE=:ISTATE2)
)) THEN
BEGIN
VNOREC_ID = :VNOREC_ID - 1;
FOR SELECT :VNOREC_ID, :VCONTREE_ID, :OBJ_ID, :VRTYPE_ID, "", "<...>", 1, :STATE FROM ZX
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO SUSPEND;
END
ELSE BEGIN
FOR SELECT CONTREE_ID, PARENT_ID, OBJ_ID, RTYPE_ID, LNAME, CODE, ORDERINT, STATE FROM CONTREE
WHERE PARENT_ID=:CONTREE_ID AND (STATE=:ISTATE1 OR STATE=:ISTATE2)
ORDER BY ORDERINT
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO BEGIN
SUSPEND;
IF (NOT EXISTS (SELECT * FROM CONTREE
WHERE PARENT_ID=:CONTREE_ID AND (STATE=:ISTATE1 OR STATE=:ISTATE2)
)) THEN
BEGIN
VCONTREE_ID = :CONTREE_ID;
VNOREC_ID = :VNOREC_ID - 1;
FOR SELECT :VNOREC_ID, :VCONTREE_ID, :OBJ_ID, 7, "", "<...>", 1, :STATE FROM ZX
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO SUSPEND;
END
ELSE BEGIN
FOR SELECT CONTREE_ID, PARENT_ID, OBJ_ID, RTYPE_ID, LNAME, CODE, ORDERINT, STATE FROM CONTREE
WHERE PARENT_ID=:CONTREE_ID AND (STATE=:ISTATE1 OR STATE=:ISTATE2)
ORDER BY FMAIN DESC, ORDERINT
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO SUSPEND;
END
END
END
END
END
← →
atruhin © (2006-07-25 13:30) [19]Опять то же самое.
FOR SELECT CONTREE_ID, PARENT_ID, OBJ_ID, RTYPE_ID, LNAME, CODE, ORDERINT, STATE FROM CONTREE
WHERE PARENT_ID=:CONTREE_ID AND (STATE=:ISTATE1 OR STATE=:ISTATE2)
ORDER BY ORDERINT
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO BEGIN
SUSPEND;
IF (NOT EXISTS (SELECT * FROM CONTREE
WHERE PARENT_ID=:CONTREE_ID AND (STATE=:ISTATE1 OR STATE=:ISTATE2)
)) THEN
BEGIN
VCONTREE_ID = :CONTREE_ID;
VNOREC_ID = :VNOREC_ID - 1;
FOR SELECT :VNOREC_ID, :VCONTREE_ID, :OBJ_ID, 7, "", "<...>", 1, :STATE FROM ZX
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO SUSPEND;
END
ELSE BEGIN
FOR SELECT CONTREE_ID, PARENT_ID, OBJ_ID, RTYPE_ID, LNAME, CODE, ORDERINT, STATE FROM CONTREE
WHERE PARENT_ID=:CONTREE_ID AND (STATE=:ISTATE1 OR STATE=:ISTATE2)
ORDER BY FMAIN DESC, ORDERINT
INTO :CONTREE_ID, :PARENT_ID, :OBJ_ID, :RTYPE_ID, :LNAME, :CODE, :ORDERINT, :STATE
DO SUSPEND;
END
Т.е. ты то присваеваешь, не понятно что потом используеш.
← →
Desdechado © (2006-07-25 13:33) [20]Для интереса, покажи 2 полученных набора данных в правильном и неправильном варианте.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.039 c