Сборка мусора, автоматический бэкап/рестор

Ремонт и восстановление баз данных InterBase, Firebird, Yaffil

Модераторы: kdv, Alexey Kovyazin

Ulme
Сообщения: 16
Зарегистрирован: 27 июн 2008, 14:31

Сборка мусора, автоматический бэкап/рестор

Сообщение Ulme » 27 июн 2008, 15:50

Есть базы А и Б, по структуре одинаковые, в работе круглосуточно
обьем А = 700мб,
обьем Б = 2гб
сервер Firebird 2.0.3

проблема
после 6-и месяцев работы на базе Б начались страшные тормоза,
при этом кол-во транзакций в день около 900 000 (по IBAnalyst'у),
авто sweep с интервалом в 20 000

в это время на базе А все пока ок, работает шустренько, отчеты строятся почти мгновенно, однако ей бэкап\рестор делается раз в месяц + кол-во транзакций в день ~200 000, в отличии от базы Б - последний раз рестор 3 месяца назад

по рекомендациям IBAnalyst'a:
для базы Б убрал плохие индексы, сделал свип, отключил автосвип, обновил статистику по индексам - всеравно запросы обрабатываются намного медленне чем для базы А.

1. что еще можно сделать по выше указанной проблеме?
2. как организовать сборку мусора? поставить на батник, который запускается в 3 часа ночи (активность клиентов минимальная, закрывать базу нельзя), + запуск проги gidx.exe для обновления планов или лучше просто раз в месяц делать рестор вручную? даже это довольно проблематично, так как через полгода баз размера больше одного гб станет около 20, и чувствую на них будут те же проблемы

п.с. кстати для базы А на момент получения статистики
OIT = 29053571
OAT = 29053572 , а для базы Б
OIT = 165210258
OAT = 165217009 , т.е. дело идет к запуску автосвипа.
значит ли такой расклад, что для базы А сборка мусора или включается очень редко, или совсем не включается?

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 27 июн 2008, 16:12

"Намного медленнее" - насколько? Какая загрузка сервера при этом? Сколько пользователей?
Почему нельзя закрывать базу?
Что за программа gidx "для обновления планов"?

Ulme
Сообщения: 16
Зарегистрирован: 27 июн 2008, 14:31

Сообщение Ulme » 27 июн 2008, 16:48

к примеру для такого запроса (запросы писались не мною, выдали как стандартный для получения отчетов)

Код: Выделить всё

select dc."Signal",dc."Driver_No", d."F", c."Radio",
                           c."AbonPlata", c."CoeffComission", c."NoPenalty", dc."GPRS", c."Pager_No",
                           sum(ao."Cost")  as "SumCost",
                           count(ao."Order_No") as "CountOrders",
                           sum(ao."DiscountSum") as "DiscountSum",
                           (select sum(pd."Summa")
                           from "PenaltyDriver" pd
                           where pd."Signal" = dc."Signal"
                           and pd."TimePenalty" >= :pBeginTime and
                           pd."TimePenalty" <= :pEndTime)
                           as "SummaPenalty",
                           (select count(cm."CustomMsg_Id") from
                           "CustomMsg" cm where cm."MsgTime" >= :pBeginTime and
                           cm."MsgTime" <= :pEndTime and cm."MsgType" = 0 and cm."Signal" = dc."Signal")
                           as "CountCustomMsg"
                                                      from  "Drivers" d, "Cars" c, "DriverCar" dc left join "ArchiveOrders" ao on
                           dc."Driver_No"=ao."Driver_No" and
                           ao."Close_Reason" = 0 and
                           ao."Run_Time" >= :pBeginTime and
                           ao."Run_Time"<= :pEndTime  and
                           ao."FormPaym" =0
                           where  dc."Signal" is not null and c."Signal"=dc."Signal" and
                           d."Driver_No" = dc."Driver_No"
                           group by dc."Signal",dc."Driver_No", d."F", c."Radio",
                           c."AbonPlata", c."CoeffComission", c."NoPenalty",
                           dc."GPRS", c."Pager_No"
для базы А

Plan
PLAN (CM INDEX (ind_CustomMsg_Signal, ind_CustomMsg_MsgTime))
PLAN (PD INDEX (PenaltyDriver_Signal_IDX))
PLAN SORT (JOIN (JOIN (DC NATURAL, AO INDEX (Ind_Driver_No, Ind_Run_Time_Archive)), D INDEX (RDB$PRIMARY5), C INDEX (RDB$33)))

Adapted Plan
PLAN (CM INDEX (ind_CustomMsg_Signal, ind_CustomMsg_MsgTime)) PLAN (PD INDEX (PenaltyDriver_Signal_IDX)) PLAN SORT (JOIN (JOIN (DC NATURAL, AO INDEX (Ind_Driver_No, Ind_Run_Time_Archive)), D INDEX (PK_Drivers), C INDEX (INTEG_38)))

------ Performance info ------
Prepare time = 16ms
Execute time = 4s 265ms
Avg fetch time = 11,91 ms
Current memory = 726 724
Max memory = 761 044
Memory buffers = 2 048
Reads from disk to cache = 653
Writes from cache to disk = 0
Fetches from cache = 10 384

для базы Б

Plan
PLAN (CM INDEX (ind_CustomMsg_MsgTime))
PLAN (PD INDEX (PenaltyDriver_Signal_IDX, PenaltyDriver_TimePenalty_IDX))
PLAN SORT (JOIN (JOIN (DC NATURAL, AO INDEX (Ind_Run_Time_Archive)), JOIN (D INDEX (RDB$PRIMARY5), C INDEX (RDB$33))))

Adapted Plan
PLAN (CM INDEX (ind_CustomMsg_MsgTime)) PLAN (PD INDEX (PenaltyDriver_Signal_IDX, PenaltyDriver_TimePenalty_IDX)) PLAN SORT (JOIN (JOIN (DC NATURAL, AO INDEX (Ind_Run_Time_Archive)), JOIN (D INDEX (PK_Drivers), C INDEX (INTEG_38))))

------ Performance info ------
Prepare time = 16ms
Execute time = 31s 594ms
Avg fetch time = 84,25 ms
Current memory = 805 808
Max memory = 806 900
Memory buffers = 2 048
Reads from disk to cache = 2 150
Writes from cache to disk = 0
Fetches from cache = 29 759 397


базу нельзя закрывать, так как она используется в диспетчерской такси, где со стороны диспетчеров с базой работает 7-8 компов, со стороны водителей около 700 джава-приложений с моб.телефонов через gprs. Естественно, что работают все круглосуточно, разве что поздно ночью заказов меньше всего.
про программу gidx - я обшибся, она для обновления статистики индексов, из gtools.
про загрузку сервера не понял вопрос, как мне это узнать? (сейчас для анализа есть только копия базы, к сожалению к серверу в ближайшую неделю доступа нет)

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 27 июн 2008, 18:18

1. Мешаешь в кучу явные и неявные запросы. Плохо! Читай статью.
2. Планы разные. Видишь? В базе "Б" в подзапросе из "CustomMsg" не участвует индекс "ind_CustomMsg_Signal". Убит/отключён?
Вообще, с индексами похоже полная Ж - спланированы неверно, раз их на каждое соединение по два надо.

Возьмусь за вознаграждение оптимизировать твой запрос (с коррекцией индексов, конечно) до времени выполнения 1 секунда и меньше :)

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 27 июн 2008, 18:36

WildSery писал(а): Возьмусь за вознаграждение оптимизировать твой запрос
Наконец-то начинаешь взрослеть :-D

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 27 июн 2008, 21:17

кстати, судя по приведенной информации, у сервера конфиг по дефолту. а для такой нагрузки надо хоть чуть-чуть, но настраивать.

Ulme
Сообщения: 16
Зарегистрирован: 27 июн 2008, 14:31

Сообщение Ulme » 28 июн 2008, 01:46

понял, что нужно пересмотеть все запросы и соответственно индексы + разобратся что такое конфигурирование сервера :oops:

и всетаки остается открытым вопрос про бэкап/рестор и сборку мусора:
> как организовать сборку мусора? поставить на батник, который
>запускается в 3 часа ночи (активность клиентов минимальная,
>закрывать базу нельзя), + запуск проги gidx.exe для обновления
>планов или лучше просто раз в месяц делать рестор вручную?

Attid
Спец
Сообщения: 377
Зарегистрирован: 14 ноя 2006, 09:58

Сообщение Attid » 28 июн 2008, 11:26

> как организовать сборку мусора? поставить на батник, который
>запускается в 3 часа ночи (активность клиентов минимальная,

нормально

>+ запуск проги gidx.exe для обновления
>планов

тоже нормально

>или лучше просто раз в месяц делать рестор вручную?

рестор не нужен

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 29 июн 2008, 11:57

Ulme писал(а):запуск проги gidx.exe для обновления
планов
Это кто такая ?

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 30 июн 2008, 10:15

Ulme писал(а):понял, что нужно пересмотеть все запросы и соответственно индексы + разобратся что такое конфигурирование сервера :oops:

и всетаки остается открытым вопрос про бэкап/рестор и сборку мусора:
> как организовать сборку мусора? поставить на батник, который
>запускается в 3 часа ночи (активность клиентов минимальная,
>закрывать базу нельзя), + запуск проги gidx.exe для обновления
>планов или лучше просто раз в месяц делать рестор вручную?
По сравнению с кривым планом все остальное конфигурирование капля в море. :)

После приведения запросов к нормальному виду подкрутить кэширование, чтоб уменьшить disk reads, но чтоб сервер не улез в своп.

Выше речь про gfix.exe ? вот и собрать им мусор.
Базу бэкапить регулярно (как того требует бизнес логика, согласно регламенту на время простоя). регулярный рестор в сторонке, только для проверки возможности рестора.

Ulme
Сообщения: 16
Зарегистрирован: 27 июн 2008, 14:31

Сообщение Ulme » 03 июл 2008, 18:26

WildSery писал(а):1. Мешаешь в кучу явные и неявные запросы. Плохо! Читай статью.
имелась в виду статья Использование неявных и явных JOIN ?
Прочитал, про ошибку в from Drivers" d, "Cars" c, "DriverCar" dc left join "ArchiveOrders" понял, но как сделать иначе?

Еще - нужно ли делать shutdown сервера для ускорения бэкапа, свипа и обновления статистики индексов? Думаю, ночью на 10 минут это вполне нормально

Attid
Спец
Сообщения: 377
Зарегистрирован: 14 ноя 2006, 09:58

Сообщение Attid » 03 июл 2008, 18:32

Ulme писал(а): Еще - нужно ли делать shutdown сервера для ускорения бэкапа, свипа и обновления статистики индексов? Думаю, ночью на 10 минут это вполне нормально
это ты где такое услышал ? для ускорения бекапа можешь делать бекап с ключем -g и шутдоун на это никак не повлияет , так же как на остальное, только если не будешь еще отстреливать конекты.

Ulme
Сообщения: 16
Зарегистрирован: 27 июн 2008, 14:31

Сообщение Ulme » 03 июл 2008, 19:35

Attid писал(а): это ты где такое услышал ?
слухи, слухи... :)

думаю, в моем варианте покатит и без ключа -g, чтоб не дергать дополнительно gfix.

главное, что шатдаун не ускорит работы администраторских функций

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 03 июл 2008, 20:27

Код: Выделить всё

from "DriverCar" dc
     join "Drivers" d on d."Driver_No" = dc."Driver_No" 
     join "Cars" c on c."Signal"=dc."Signal"
     left join "ArchiveOrders" ao on ao."Driver_No" = dc."Driver_No" and
                                     ao."Close_Reason" = 0 and
                                     ao."Run_Time" between :pBeginTime and :pEndTime and
                                     ao."FormPaym" = 0
  where dc."Signal" is not null
На самом деле, я не пытался вникнуть в возможное распределение данных у тебя в таблицах, возможно, нужно начинать с ArchiveOrders и справа клеить остальное.

gbak без "-g" ну никак не заменит gfix. Читай про сборку мусора.
Шатдаун БД нужен в одном случае - если типичные клиенты - это долговисящие транзакции (или ещё хуже, CommitRetaining, например, так BDE делает), которые удерживают мусор в БД. Тогда их выгон даст возможность собрать этот самый мусор.

Ulme
Сообщения: 16
Зарегистрирован: 27 июн 2008, 14:31

Сообщение Ulme » 04 июл 2008, 19:04

[quote="WildSery"][/quote]

спасибо за помощь, но:

//Убрал пару больших просчетов полей("SummaPenalty","CountCustomMsg"), чтобы сосредоточится на основном. Параметры :pBeginTime и :pEndTime одинаковы во всех 3-х запросах
Запрос №1, как вы мне порекомендовали

Код: Выделить всё

select dc."Signal",dc."Driver_No", d."F", c."Radio",
                           c."AbonPlata", c."CoeffComission", c."NoPenalty", dc."GPRS", c."Pager_No",
                           sum(ao."Cost")  as "SumCost",
                           count(ao."Order_No") as "CountOrders",
                           sum(ao."DiscountSum") as "DiscountSum"
                          

                           from "DriverCar" dc
                           join "Drivers" d on d."Driver_No" = dc."Driver_No"
                           join "Cars" c on c."Signal"=dc."Signal"
                           left join "ArchiveOrders" ao on ao."Driver_No" = dc."Driver_No" and
                                     ao."Close_Reason" = 0 and 
                                     ao."Run_Time" between :pBeginTime and :pEndTime and 
                                     ao."FormPaym" = 0
                           where dc."Signal" is not null and c."Signal"=dc."Signal" and
                           d."Driver_No" = dc."Driver_No"
                           group by dc."Signal",dc."Driver_No", d."F", c."Radio",
                           c."AbonPlata", c."CoeffComission", c."NoPenalty",
                           dc."GPRS", c."Pager_No"
Plan
PLAN SORT (JOIN (JOIN (DC NATURAL, C INDEX (RDB$33), D INDEX (RDB$PRIMARY5)), AO INDEX (Ind_Run_Time_Archive)))

Adapted Plan
PLAN SORT (JOIN (JOIN (DC NATURAL, C INDEX (INTEG_38), D INDEX (PK_Drivers)), AO INDEX (Ind_Run_Time_Archive)))

------ Performance info ------
Prepare time = 32ms
Execute time = 40s 78ms
Avg fetch time = 106,87 ms
Current memory = 899 028
Max memory = 916 964
Memory buffers = 2 048
Reads from disk to cache = 997 891
Writes from cache to disk = 0
Fetches from cache = 26 069 010


Запрос №2, начал с ArchiveOrders и клеил справа остальное

Код: Выделить всё

select dc."Signal",dc."Driver_No", d."F", c."Radio",
                           c."AbonPlata", c."CoeffComission", c."NoPenalty", dc."GPRS", c."Pager_No",
                           sum(ao."Cost")  as "SumCost",
                           count(ao."Order_No") as "CountOrders",
                           sum(ao."DiscountSum") as "DiscountSum"

                           from "ArchiveOrders" ao right join "DriverCar" dc on
                           ao."Driver_No" = dc."Driver_No" and
                                     ao."Close_Reason" = 0 and 
                                     ao."Run_Time" between :pBeginTime and :pEndTime and 
                                     ao."FormPaym" = 0
                           join "Drivers" d on d."Driver_No" = dc."Driver_No"
                           join "Cars" c on c."Signal"=dc."Signal"

                           where dc."Signal" is not null and c."Signal"=dc."Signal" and
                           d."Driver_No" = dc."Driver_No"
                           group by dc."Signal",dc."Driver_No", d."F", c."Radio",
                           c."AbonPlata", c."CoeffComission", c."NoPenalty",
                           dc."GPRS", c."Pager_No"
Plan
PLAN SORT (JOIN (JOIN (DC NATURAL, AO INDEX (Ind_Run_Time_Archive)), JOIN (D INDEX (RDB$PRIMARY5), C INDEX (RDB$33))))

Adapted Plan
PLAN SORT (JOIN (JOIN (DC NATURAL, AO INDEX (Ind_Run_Time_Archive)), JOIN (D INDEX (PK_Drivers), C INDEX (INTEG_38))))

------ Performance info ------
Prepare time = 31ms
Execute time = 39s 547ms
Avg fetch time = 105,46 ms
Current memory = 901 664
Max memory = 916 964
Memory buffers = 2 048
Reads from disk to cache = 997 897
Writes from cache to disk = 0
Fetches from cache = 26 069 010


Запрос №3, старый, со смешанием явных и неявных джойнов

Код: Выделить всё

select dc."Signal",dc."Driver_No", d."F", c."Radio",
                           c."AbonPlata", c."CoeffComission", c."NoPenalty", dc."GPRS", c."Pager_No",
                           sum(ao."Cost")  as "SumCost",
                           count(ao."Order_No") as "CountOrders",
                           sum(ao."DiscountSum") as "DiscountSum"

                           from  "Drivers" d, "Cars" c, "DriverCar" dc left join "ArchiveOrders" ao on
                           dc."Driver_No"=ao."Driver_No" and
                           ao."Close_Reason" = 0 and
                           ao."Run_Time" >= :pBeginTime and
                           ao."Run_Time"<= :pEndTime  and
                           ao."FormPaym" =0
                           where  dc."Signal" is not null and c."Signal"=dc."Signal" and
                           d."Driver_No" = dc."Driver_No"
                           group by dc."Signal",dc."Driver_No", d."F", c."Radio",
                           c."AbonPlata", c."CoeffComission", c."NoPenalty",
                           dc."GPRS", c."Pager_No"
Plan
PLAN SORT (JOIN (JOIN (DC NATURAL, AO INDEX (Ind_Run_Time_Archive)), JOIN (D INDEX (RDB$PRIMARY5), C INDEX (RDB$33))))

Adapted Plan
PLAN SORT (JOIN (JOIN (DC NATURAL, AO INDEX (Ind_Run_Time_Archive)), JOIN (D INDEX (PK_Drivers), C INDEX (INTEG_38))))

------ Performance info ------
Prepare time = 16ms
Execute time = 39s 531ms
Avg fetch time = 105,42 ms
Current memory = 900 256
Max memory = 916 964
Memory buffers = 2 048
Reads from disk to cache = 997 897
Writes from cache to disk = 0
Fetches from cache = 26 069 010

как видно, во всех 3-х запросах время выполнения одинаково :shock: :(

теперь по поводу индексов: используются индексы с высокой селективностью, но не пойму почему для dc."Signal" и dc."Driver_No" не берутся мои индексы вместо DC NATURAL(см планы)? Они есть, и они уникальны (все индексы ascending).

mustafa
Сообщения: 67
Зарегистрирован: 07 мар 2006, 17:53

Сообщение mustafa » 05 июл 2008, 09:19

Ulme писал(а):теперь по поводу индексов: используются индексы с высокой селективностью, но не пойму почему для dc."Signal" и dc."Driver_No" не берутся мои индексы вместо DC NATURAL(см планы)? Они есть, и они уникальны (все индексы ascending).
Запрос №1
по dc."Driver_No" у тебя left join - индекс и не должен использоваться.
по dc."Signal" у тебя только одно условие - where dc."Signal" is not null - должен ли тут использоваться индекс - хз.
попробуй добавить что нибудь типа dc."Signal" >= минимально_допустимое_значение_поля, всё равно результат сравнения будет актуален только для not null значений.

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 05 июл 2008, 12:15

для IS NOT NULL индекс никогда не используется

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 07 июл 2008, 13:00

С этим лефт жойном у тебя какая-то засада.
Можешь метаданные привести? И статистику индексов.

Ulme
Сообщения: 16
Зарегистрирован: 27 июн 2008, 14:31

Сообщение Ulme » 07 июл 2008, 14:01

mustafa писал(а):
спасибо, разобрался

2 WildSery
заранее извеняюсь за огромное сообщение

метаданные по использующимся в запросе таблицам ArchiveOrders, DriverCar, Drivers, Cars

Код: Выделить всё

/******************************************************************************/
/***          Generated by IBExpert 2005.12.21 07.07.2008 12:35:30          ***/
/******************************************************************************/

SET SQL DIALECT 3;

SET NAMES WIN1251;

CREATE DATABASE 'alex:D:\BD\NEWTAXI2.GDB'
USER 'SYSDBA' PASSWORD 'masterkey'
PAGE_SIZE 4096
DEFAULT CHARACTER SET WIN1251;



/******************************************************************************/
/***                                 Tables                                 ***/
/******************************************************************************/



CREATE TABLE "ArchiveOrders" (
    "Order_No"            INTEGER NOT NULL,
    "Creation_Time"       TIMESTAMP DEFAULT 'Now' NOT NULL,
    "Created_Disp"        INTEGER,
    "Type"                SMALLINT DEFAULT 0 NOT NULL,
    "Client_No"           INTEGER,
    "Address"             "DAddress",
    "Apartment"           INTEGER,
    "Phone"               "DPhone",
    "Req_Start_Time"      TIMESTAMP,
    "Run_Time"            TIMESTAMP,
    "Run_Disp"            INTEGER,
    "Signal"              INTEGER,
    "Route_Length"        "DDistance" NOT NULL,
    "Route_Time"          INTEGER DEFAULT 0 NOT NULL,
    "Cost"                "DMoney",
    "Idle_Time"           INTEGER DEFAULT 0 NOT NULL,
    "Idle_Cost"           "DMoney",
    "Comment"             "DComment",
    "Req_Time_Prev"       TIMESTAMP,
    "Universal"           INTEGER default 0 NOT NULL,
    "Close_Time"          TIMESTAMP,
    "Close_Disp"          INTEGER,
    "Close_Reason"        INTEGER default 0 NOT NULL,
    "Driver_No"           INTEGER,
    "DriverF"             "DName",
    "FormPaym"            INTEGER default 0 NOT NULL,
    "Discount"            INTEGER default 0 NOT NULL,
    "NickName"            "DName",
    "Line"                INTEGER,
    "Entrance"            INTEGER,
    "Dest"                VARCHAR(80),
    "IsKievStar"          INTEGER default 0 NOT NULL,
    "Sector"              VARCHAR(20),
    "Attention"           INTEGER,
    "CurOrder_No"         INTEGER,
    "Elit"                INTEGER default 0 NOT NULL,
    "Zaezd"               "DComment",
    "Executed_Disp"       INTEGER DEFAULT 0 NOT NULL,
    "IsNewOrder"          INTEGER default 0 NOT NULL,
    "Perezvon_Disp"       INTEGER default 0 NOT NULL,
    "Baggage"             INTEGER default 0 NOT NULL,
    "Animal"              INTEGER default 0 NOT NULL,
    "ClientName"          "DName",
    "OutCityLength"       "DDistance" default 0 NOT NULL,
    "OutCityCost"         "DMoney" default 0 NOT NULL,
    "IsDoubleOutCityKm"   INTEGER default 0 NOT NULL,
    "IsViaCity"           INTEGER default 0 NOT NULL,
    "PassHand"            INTEGER default 0 NOT NULL,
    "Check"               INTEGER default 0 NOT NULL,
    "TimeWay"             INTEGER default 0 NOT NULL,
    "TimeWayHours"        TIMESTAMP,
    "KeySectorLocation"   INTEGER default 0 NOT NULL,
    "TaxiColumnKey"       INTEGER default 0 NOT NULL,
    "DiscountSum"         DECIMAL(15,2),
    "Action"              INTEGER default 0 NOT NULL,
    "SubCard"             "DName",
    "Accounts_Id"         INTEGER DEFAULT 0 NOT NULL,
    "AddCost"             DECIMAL(15,2) DEFAULT 0 NOT NULL,
    "PointX"              INTEGER DEFAULT 0 NOT NULL,
    "PointY"              INTEGER DEFAULT 0 NOT NULL,
    "TaxiColumnCreated"   INTEGER DEFAULT 0 NOT NULL,
    "SendStatus"          INTEGER DEFAULT 0 NOT NULL,
    "KeyFactor"           INTEGER DEFAULT 0 NOT NULL,
    "OnlineOrder_Status"  INTEGER DEFAULT 0 NOT NULL,
    "OnlineOrder_No"      INTEGER DEFAULT 0 NOT NULL,
    "Taxi_Id_To"          INTEGER,
    "Taxi_Id_From"        INTEGER
);

CREATE TABLE "Cars" (
    "Car_No"          "DCarNo",
    "Marka"           VARCHAR(30) NOT NULL,
    "Year"            INTEGER,
    "Cusov_No"        VARCHAR(20),
    "Comment"         "DComment",
    "Signal"          INTEGER NOT NULL,
    "Pasp_No"         VARCHAR(30),
    "Color"           VARCHAR(30),
    "CarTruck"        INTEGER,
    "CarElite"        INTEGER,
    "Tariff"          "DComment",
    "Radio"           INTEGER default 0 NOT NULL,
    "AbonPlata"       INTEGER default 0 NOT NULL,
    "Pager_No"        INTEGER,
    "Car_Id"          INTEGER default 0 NOT NULL,
    "CoeffComission"  DECIMAL(15,2) DEFAULT 1 NOT NULL,
    "NoPenalty"       INTEGER default 0 NOT NULL
);

CREATE TABLE "DriverCar" (
    "Driver_No"            INTEGER NOT NULL,
    "State"                SMALLINT DEFAULT 1 NOT NULL,
    "Open_Time"            TIMESTAMP,
    "Close_Time"           TIMESTAMP,
    "Close_Timeout"        INTEGER DEFAULT 0,
    "Signal"               INTEGER,
    "CloseTimePreview"     TIMESTAMP,
    "Present_State"        INTEGER default 0 NOT NULL,
    "Bonus"                INTEGER default 0 NOT NULL,
    "Sector"               VARCHAR(20),
    "RegTime"              TIMESTAMP default 'now' NOT NULL,
    "MinWay"               "DDistance" default 0 NOT NULL,
    "PointX"               INTEGER default 0 NOT NULL,
    "PointY"               INTEGER default 0 NOT NULL,
    "IsOnOrder"            INTEGER default 0 NOT NULL,
    "RegAddress"           "DAddress",
    "LastOrderTimeRefuse"  TIMESTAMP default '30.06.2004 18:00:00' NOT NULL,
    "Open_Time_Sector"     TIMESTAMP default 'now' NOT NULL,
    "Close_Time_Sector"    TIMESTAMP default 'now' NOT NULL,
    "Open_Time_Order"      TIMESTAMP default 'now' NOT NULL,
    "Close_Time_Order"     TIMESTAMP default 'now' NOT NULL,
    "Close_Reason"         "DComment",
    "Duty"                 INTEGER default 0 NOT NULL,
    "DutyZalog"            "DAddress",
    "Sdal"                 INTEGER default 0 NOT NULL,
    "SdalZalog"            "DAddress",
    "OrderCount"           INTEGER default 0 NOT NULL,
    "OrderRefuse"          INTEGER default 0 NOT NULL,
    "WasInOffice"          INTEGER DEFAULT 0 NOT NULL,
    "Auto"                 INTEGER DEFAULT 0 NOT NULL,
    "Password"             VARCHAR(16),
    "LastChange"           TIMESTAMP DEFAULT 'now',
    GPRS                   INTEGER DEFAULT 0 NOT NULL
);

CREATE TABLE "Drivers" (
    "Driver_No"  INTEGER NOT NULL,
    F            "DName" NOT NULL,
    I            "DName",
    O            "DName",
    "Address1"   "DAddress",
    "Phone1"     "DPhone",
    "Address2"   "DAddress",
    "Phone2"     "DPhone",
    "MPhone"     "DPhone",
    "Comment"    "DComment"
);



/******************************************************************************/
/***                           Unique Constraints                           ***/
/******************************************************************************/

ALTER TABLE "Cars" ADD UNIQUE ("Signal");
ALTER TABLE "Cars" ADD CONSTRAINT "UNQ_Car_No" UNIQUE ("Car_No");


/******************************************************************************/
/***                              Primary Keys                              ***/
/******************************************************************************/

ALTER TABLE "Cars" ADD CONSTRAINT "PK_Cars" PRIMARY KEY ("Car_Id");
ALTER TABLE "DriverCar" ADD CONSTRAINT "PK_DriverCar" PRIMARY KEY ("Driver_No");
ALTER TABLE "Drivers" ADD CONSTRAINT "PK_Drivers" PRIMARY KEY ("Driver_No");


/******************************************************************************/
/***                              Foreign Keys                              ***/
/******************************************************************************/

ALTER TABLE "DriverCar" ADD CONSTRAINT "FK_DriverCar_Signal" FOREIGN KEY ("Signal") REFERENCES "Cars" ("Signal") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "DriverCar" ADD CONSTRAINT "FK_Drivers_Driver_No" FOREIGN KEY ("Driver_No") REFERENCES "Drivers" ("Driver_No") ON DELETE CASCADE ON UPDATE CASCADE;


/******************************************************************************/
/***                                Indices                                 ***/
/******************************************************************************/

CREATE DESCENDING INDEX ARCHIVEORDERS_IDX1 ON "ArchiveOrders" ("Run_Time");
CREATE INDEX "Ind_Close_Time" ON "ArchiveOrders" ("Close_Time");
CREATE INDEX "Ind_Phone" ON "ArchiveOrders" ("Phone");
CREATE INDEX "Ind_Run_Time_Archive" ON "ArchiveOrders" ("Run_Time");
CREATE INDEX "ind_Archive_Order_No" ON "ArchiveOrders" ("Order_No");
CREATE INDEX DRIVERCAR_IDX1 ON "DriverCar" ("CloseTimePreview");
CREATE INDEX DRIVERCAR_IDX2 ON "DriverCar" ("IsOnOrder");
CREATE INDEX DRIVERCAR_IDX3 ON "DriverCar" ("MinWay");
CREATE INDEX "DriverCar_RegTime" ON "DriverCar" ("RegTime");
статистика по индексам из этих 4-х таблиц

Код: Выделить всё

ArchiveOrders (139)

    Index ARCHIVEORDERS_IDX1 (0)
	Depth: 3, leaf buckets: 1219, nodes: 566565
	Average data length: 2.70, total dup: 8471, max dup: 3
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 1
	    40 - 59% = 0
	    60 - 79% = 0
	    80 - 99% = 1218

    Index Ind_Close_Time (1)
	Depth: 3, leaf buckets: 1295, nodes: 566565
	Average data length: 2.70, total dup: 4090, max dup: 3
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 142
	    60 - 79% = 0
	    80 - 99% = 1153

    Index Ind_Phone (10)
	Depth: 3, leaf buckets: 1452, nodes: 566566
	Average data length: 0.94, total dup: 429110, max dup: 23468
	Fill distribution:
	     0 - 19% = 2
	    20 - 39% = 0
	    40 - 59% = 624
	    60 - 79% = 498
	    80 - 99% = 328

    Index Ind_Run_Time_Archive (12)
	Depth: 3, leaf buckets: 2347, nodes: 566565
	Average data length: 2.71, total dup: 8471, max dup: 3
	Fill distribution:
	     0 - 19% = 9
	    20 - 39% = 1
	    40 - 59% = 2101
	    60 - 79% = 232
	    80 - 99% = 4

    Index ind_Archive_Order_No (11)
	Depth: 3, leaf buckets: 1943, nodes: 566565
	Average data length: 1.01, total dup: 364, max dup: 2
	Fill distribution:
	     0 - 19% = 46
	    20 - 39% = 0
	    40 - 59% = 1781
	    60 - 79% = 99
	    80 - 99% = 17


Cars (128)

    Index RDB$1 (1)
	Depth: 2, leaf buckets: 2, nodes: 375
	Average data length: 5.05, total dup: 0, max dup: 0
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 2
	    60 - 79% = 0
	    80 - 99% = 0

    Index RDB$33 (0)
	Depth: 1, leaf buckets: 1, nodes: 375
	Average data length: 1.02, total dup: 0, max dup: 0
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 1
	    80 - 99% = 0

    Index RDB$PRIMARY13 (2)
	Depth: 1, leaf buckets: 1, nodes: 375
	Average data length: 1.07, total dup: 0, max dup: 0
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 1
	    80 - 99% = 0


DriverCar (133)

    Index DRIVERCAR_IDX1 (5)
	Depth: 2, leaf buckets: 2, nodes: 909
	Average data length: 0.02, total dup: 906, max dup: 495
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 2
	    80 - 99% = 0

    Index DRIVERCAR_IDX2 (4)
	Depth: 1, leaf buckets: 1, nodes: 417
	Average data length: 0.00, total dup: 416, max dup: 416
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 1
	    80 - 99% = 0

    Index DRIVERCAR_IDX3 (6)
	Depth: 1, leaf buckets: 1, nodes: 417
	Average data length: 0.02, total dup: 416, max dup: 416
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 1
	    80 - 99% = 0

    Index DriverCar_RegTime (1)
	Depth: 2, leaf buckets: 2, nodes: 421
	Average data length: 3.32, total dup: 1, max dup: 1
	Fill distribution:
	     0 - 19% = 1
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 0
	    80 - 99% = 1

    Index RDB$FOREIGN11 (7)
	Depth: 1, leaf buckets: 1, nodes: 417
	Average data length: 1.07, total dup: 0, max dup: 0
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 1
	    80 - 99% = 0

    Index RDB$FOREIGN47 (8)
	Depth: 1, leaf buckets: 1, nodes: 417
	Average data length: 0.93, total dup: 41, max dup: 41
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 1
	    80 - 99% = 0

    Index RDB$PRIMARY12 (0)
	Depth: 1, leaf buckets: 1, nodes: 417
	Average data length: 1.07, total dup: 0, max dup: 0
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 1
	    80 - 99% = 0


Drivers (145)

    Index RDB$PRIMARY5 (0)
	Depth: 1, leaf buckets: 1, nodes: 417
	Average data length: 1.07, total dup: 0, max dup: 0
	Fill distribution:
	     0 - 19% = 0
	    20 - 39% = 0
	    40 - 59% = 0
	    60 - 79% = 1
	    80 - 99% = 0

Ulme
Сообщения: 16
Зарегистрирован: 27 июн 2008, 14:31

Сообщение Ulme » 07 июл 2008, 15:12

сделал бекап/рестор, база с 1,4гб стала занимать 880мб

после этого запрос делается за 30-90 ms
статистика по индексам показала, что теперь все заполнения страниц в пределах 80-99%, в отличии от того, как было раньше (см выше)

т.е. упаковка данных так ускорила запрос? или что то еще произошло?
до бекап/рестора делал и свип и обновление статистики индексов

Ответить