|
|
|
Медленый запрос (из 5-ти таблиц). Как его ускорить?
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. Система: MS SQL Server 2000 и Visual FoxPro 8.0. Проблема следующая – запрос оформленный в ХП работает очень медленно (где-то 25 секунд) CREATE PROCEDURE CurListHousePassport @IDPersAcc_Shadow INT, @CurDateWork_Shadow DATETIME, @UserID_Shadow INT AS /*ХП возвращает список записей для паспортного стола за текущую дату @CurDateWork_Shadow*/ SET DATEFORMAT DMY SELECT PersAcc.NumberPA, RTRIM(Roomer.Surname) + ' ' + RTRIM(Roomer.Name) + ' ' + RTRIM(Roomer.Patronymic) AS FIO, House.CodeHouse, RTRIM(House.AddrStreet) + ' д.' + RTRIM(House.AddrHouse) + ' к.' + RTRIM(House.AddrFrame) + ' кв.' + RTRIM(DetailsPersAcc.NumberFlat) AS Address, PersAcc.NumberJEU, House.Oblast, House.Region, House.Settlement, House.AddrStreet, House.AddrHouse, House.AddrFrame, DetailsPersAcc.NumberFlat, DetailsPersAcc.AmountRoom, DetailsPersAcc.AmountSeparateRoom, DetailsPersAcc.AmountRoomers, DetailsPersAcc.AmountPrivileger, DetailsPersAcc.AmountTenants, DetailsPersAcc.Floor, DetailsPersAcc.TotalSpace, DetailsPersAcc.FloorSpace, DetailsPersAcc.PaySpace, DetailsPersAcc.KitchenSpace, DetailsPersAcc.HeatSpace, DetailsPersAcc.Phone, DetailsPersAcc.NumberOrder, DetailsPersAcc.DateOrder, DetailsPersAcc.DetailsOrder, DetailsPersAcc.Balcony, DetailsPersAcc.TypeRoom, House.AmountFloor, House.Material, DetailsPersAcc.IDHouse, Roomer.Surname, Roomer.Name, Roomer.Patronymic, Roomer.Sex, Roomer.Alliance, Roomer.Nationality, Roomer.Birthday, Roomer.Master, Roomer.NumberPassport, Roomer.SeriesPassport, Roomer.OrganizationPassport, Roomer.DateIssuePassport, Roomer.DateValidPassport, Roomer.Conscript, Roomer.OblastBirthday, Roomer.RegionBirthday, Roomer.CityBirthday, Roomer.Citizenship, Roomer.NumberPassportID, Roomer.WorkPlace, Roomer.Children, RoomerArrival.DateArrival, RoomerArrival.OblastArrival, RoomerArrival.RegionArrival, RoomerArrival.CityArrival, RoomerArrival.AddrStreetArrival, RoomerArrival.AddrHouseArrival, RoomerArrival.AddrFrameArrival, RoomerArrival.AddrFlatArrival, PersAcc.ID AS IDPA, PersAcc.IDPersAcc, Roomer.ID AS IDR, RoomerArrival.ID AS IDRA, House.ID AS IDH FROM PersAcc INNER JOIN Roomer ON PersAcc.IDPersAcc = Roomer.IDPersAcc INNER JOIN RoomerArrival ON PersAcc.IDPersAcc = RoomerArrival.IDPersAcc INNER JOIN DetailsPersAcc ON PersAcc.IDPersAcc = DetailsPersAcc.IDPersAcc INNER JOIN House ON DetailsPersAcc.IDHouse = House.IDHouse WHERE (@CurDateWork_Shadow BETWEEN PersAcc.DateStart AND PersAcc.DateEnd) AND (@CurDateWork_Shadow <> PersAcc.DateEnd) AND (@CurDateWork_Shadow BETWEEN Roomer.DateStart AND Roomer.DateEnd) AND (@CurDateWork_Shadow <> Roomer.DateEnd) AND (Roomer.Master = 1) AND (@CurDateWork_Shadow BETWEEN RoomerArrival.DateStart AND RoomerArrival.DateEnd) AND (@CurDateWork_Shadow <> RoomerArrival.DateEnd) AND (RoomerArrival.Master = 1) AND (@CurDateWork_Shadow BETWEEN DetailsPersAcc.DateStart AND DetailsPersAcc.DateEnd) AND (@CurDateWork_Shadow <> DetailsPersAcc.DateEnd) AND (@CurDateWork_Shadow BETWEEN House.DateStart AND House.DateEnd) AND (@CurDateWork_Shadow <> House.DateEnd) GO В результате выполнения запроса получается 4916 записей (таблицы PersAcc, DetailsPersAcc, Roomer, RoomerArrival, RoomerDeparture имеют тоже по 4916 записей, только таблица House имеет 50 записей). Я использую в форме (form1) в DataEnvironment специальный CursorAdapter1 с алиасом – housepassport в который, по свойству AutoOpen получаю данные следующим способом: stringSQL = "EXEC CurListHousePassport ?CurrentDateWorking, ?UserID" sqlResult = SQLEXEC(connectHandle2, stringSQL, "housepassport") IF sqlResult < 0 = MESSAGEBOX('Error – CurListHousePassport', 16, ‘Error, Query SQL') ENDIF А на форме form1 есть Grid1, к которому я в RecordSource прописываю housepassport (т.е. полученные данные) Так вот я при нажатии кнопки ”добавить” на форме form1 вызывается другая форма (form2), в которой вызывается ХП AddPersAcc и происходит опять обновление курсора housepassport: THISFORM.LockScreen = .T. THISFORM.Grid1.RecordSource = "" stringSQL = "EXEC CurListHousePassport?CurrentDateWorking, ?UserID" sqlResult = SQLEXEC(connectHandle2, stringSQL, "housepassport") IF sqlResult < 0 = MESSAGEBOX('Error - CurListHousePassport', 16, 'Error SQL') ELSE SELECT housepassport LOCATE FOR housepassport.IDPA = uniqIDPersAcc ENDIF THISFORM.Grid1.RecordSource = "housepassport" stringSQL = "EXEC CurListHumanPassport?CurrentDateWorking, ?UserID" sqlResult = SQLEXEC(connectHandle2, stringSQL, "humanpassport") IF sqlResult < 0 = MESSAGEBOX('Error - CurListHumanPassport', 16, 'Error SQL') ENDIF SELECT housepassport THISFORM.Refresh() THISFORM.LockScreen = .F. Есть ли какие-либо варианты решения этой проблемы, т.е. ускорить выполнение запроса? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 17:35 |
|
||
|
Медленый запрос (из 5-ти таблиц). Как его ускорить?
|
|||
|---|---|---|---|
|
#18+
Вероятно индексов не хватает. Сделай для Id каждой таблицы, и для полей, которые во WHERE попробуй конструкцию @CurDateWork_Shadow BETWEEN Table.DateStart AND Table.DateEnd AND @CurDateWork_Shadow <> Table.DateEnd заменить на @CurDateWork_Shadow >= Table.DateStart AND @CurDateWork_Shadow < Table.DateEnd Query Analyzer`ом план выполнения запроса посмотри. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 18:04 |
|
||
|
Медленый запрос (из 5-ти таблиц). Как его ускорить?
|
|||
|---|---|---|---|
|
#18+
В принципе ваш вопрос больше относиться к SQL серверу, чем к VFP, но попробую ответить: Скопируйте запрос (не хранимую процедуру) в QA (Query Analyzer) и попробуйте выполнить его там. Если время выполнения опять велико, то: 1. Проверьте наличие индексов по тем полям, по которым осуществляется JOIN - ны. Если индексов нет, то создайте их. 2. Необходимы индексы по всем селективным полям (PersAcc.DateStart, PersAcc.DateEnd и пр. ) по которым производится поиск. 3. Наиболее быстро работает поиск по кластерному индексу. 4. Если индексы есть, то возможно не актуальна статистика по ним - обновите статистику по индексам. 5. Каковы данные SQL сервера: версия, память, процессор, .... С уважением, Алексей ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 18:30 |
|
||
|
Медленый запрос (из 5-ти таблиц). Как его ускорить?
|
|||
|---|---|---|---|
|
#18+
Благодарю и DimaT и Aleksey-K за ответы. Индексов я не создавал (попробую создать). Попутно вопрос к Алексею Климову, что значит "не актуальна статистика по индексам?" и как обновлятьстатистику по индексам? С уважением, Алексей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 18:42 |
|
||
|
Медленый запрос (из 5-ти таблиц). Как его ускорить?
|
|||
|---|---|---|---|
|
#18+
1. Индекс по первичному ключу таблицы создается автоматически при создании самого ключа, т.е. считайте что они у вас есть. А сами PK (первичные ключи) я полагаю у вас присутствуют в базе данных для всех таблиц. Индексы по Foreign Key (внешние ключи) надо создавать самим. 2. Статистка по индексам описывает некоторые общие значения индексного ключа (хотя статистику можно создать и не для поля без ключа). Статистика создается и обновляется автоматически по индексам при соот. установках базы данных (см. рисунок). Статистика включает: кол-во записей в таблице, макс. и минимальное значение ключа, дата и время создания и обновления, актуальность, кол-во записей использ. при создании (обновлении) статистики, гистограмма распределения кол-ва записей по значениям ключа и пр. Главное назначение статистики - дать информацию оптимизатору запроса для принятия решения об использовании или не использовании данного индекса при построении плана запроса. Даже если статистика создана и не удалена (а она удаляется, например, при команде TRUNCATE TABLE), она не всегда актуальна и требует ручного сопровождения. Как правило, сопровождение статистики поручают самому SQL Server (точнее - SQL Server Agent), когда настраивают сопровождение базы данных с помощью DataBase Maintanance Plan Wizard. Т.е., обычно ночью, запускается JOB, который обновляют статистику по всем индексам. Вручную ее проще всего обновить через QA->Tools->ManageStatistics. С уважением, Алексей ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2006, 19:01 |
|
||
|
|

start [/forum/topic.php?fid=41&msg=33584943&tid=1592181]: |
0ms |
get settings: |
8ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
165ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
45ms |
get tp. blocked users: |
1ms |
| others: | 225ms |
| total: | 483ms |

| 0 / 0 |
