Оптимизация процедуры
Добавлено: 05 ноя 2004, 14:43
Здравствуйте! Помогите, плиз, с медленной ХП.
Заранее извините за длинный пост.
FB 1.5.1
Имеем вьюху (5000 записей). В Person ~2000 записей.
А вот собственно и ХП, которая тормозит:
Спасибо.
Заранее извините за длинный пост.
FB 1.5.1
Имеем вьюху (5000 записей). В Person ~2000 записей.
Код: Выделить всё
CREATE VIEW VW$ANSWER(
ID_PERSON,
ID_ACTION,
ID_TOWN)
AS
SELECT A.ID_PERSON
, A.ID_ACTION
, P.ID_TOWN
FROM ANSWER A LEFT JOIN PERSON P ON A.ID_PERSON = P.ID_PERSON
;
Код: Выделить всё
CREATE PROCEDURE QRY$PARTICIPANT (
ID_ACTION INTEGER,
INPUT_DATE DATE)
RETURNS (
ID_PERSON INTEGER,
ID_TOWN INTEGER,
SEX VARCHAR(1),
AGE INTEGER)
AS
BEGIN
/* Список лиц участвующих в акции на определенную дату */
FOR
SELECT P.ID_PERSON
, P.ID_TOWN
, P.SEX
, (CURRENT_DATE - P.DOB) / 365
FROM PERSON P
WHERE EXISTS(SELECT A.ID_PERSON
FROM ANSWER A
WHERE A.ID_ACTION = :ID_ACTION
AND A.DATE_RECEPTION <= :INPUT_DATE
AND A.ID_PERSON = P.ID_PERSON)
INTO :ID_PERSON
, :ID_TOWN
, :SEX
, :AGE
DO BEGIN
SUSPEND;
END
END
Код: Выделить всё
BEGIN
/* Отчет в разрезе возростных категорий */
FOR
SELECT A.ID_TOWN
, COUNT(*)
FROM VW$ANSWER A
WHERE A.ID_ACTION = :ID_ACTION
GROUP BY 1
INTO :ID_TOWN
, :COUPON
DO
BEGIN
SELECT T.REGION_NAME
, T.DISTRICT_NAME
, T.NAME
FROM VW$TOWN T
WHERE T.ID_TOWN = :ID_TOWN
INTO :REGION
, :DISTRICT
, :TOWN;
SELECT 0, 0, 0, 0, 0, 0, 0
FROM RDB$DATABASE
INTO :MEN, :AGE18_23, :AGE24_30, :AGE31_40, :AGE41_50, :AGE51_60, :AGE60_;
SELECT COUNT(*)
FROM QRY$PARTICIPANT(:ID_ACTION, :INPUT_DATE)
WHERE SEX = 'м'
AND ID_TOWN = :ID_TOWN
INTO :MEN;
FOR SELECT
CASE
WHEN (AGE BETWEEN 18 AND 23) THEN '1'
WHEN (AGE BETWEEN 24 AND 30) THEN '2'
WHEN (AGE BETWEEN 31 AND 40) THEN '3'
WHEN (AGE BETWEEN 41 AND 50) THEN '4'
WHEN (AGE BETWEEN 51 AND 60) THEN '5'
WHEN (AGE > 60) THEN '6'
ELSE 0
END
, COUNT(*)
FROM QRY$PARTICIPANT(:ID_ACTION, :INPUT_DATE)
WHERE ID_TOWN = :ID_TOWN
GROUP BY 1
INTO :TYPE_
, :CNT_TYPE
DO BEGIN
IF (:TYPE_ = '1') THEN AGE18_23 = :CNT_TYPE;
IF (:TYPE_ = '2') THEN AGE24_30 = :CNT_TYPE;
IF (:TYPE_ = '3') THEN AGE31_40 = :CNT_TYPE;
IF (:TYPE_ = '4') THEN AGE41_50 = :CNT_TYPE;
IF (:TYPE_ = '5') THEN AGE51_60 = :CNT_TYPE;
IF (:TYPE_ = '6') THEN AGE60_ = :CNT_TYPE;
END
CNT_PERSON = AGE18_23 + AGE24_30 + AGE31_40 + AGE41_50 + AGE51_60 + AGE60_;
WOMEN = :CNT_PERSON - :MEN;
SUSPEND;
END
END
Код: Выделить всё
------ Performance info ------
Prepare time = 0ms
Execute time = 6s 250ms
Avg fetch time = 208,33 ms
Current memory = 4 215 804
Max memory = 4 535 828
Memory buffers = 2 048
Reads from disk to cache = 0
Writes from cache to disk = 4
Fetches from cache = 7 693 353
PLAN SORT (JOIN (A A INDEX (FK_ACTION__ANSWER), A P INDEX (PK_PERSON)))
SORT ()(RDB$DATABASE NATURAL)
JOIN (JOIN (JOIN (T T INDEX (PK_TOWN),T D INDEX (PK_DISTRICT)),
T R INDEX (PK_REGION)),T TT INDEX (PK_TOWN_TYPE))