Access + DAO = торможение

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Access + DAO = торможение

Сообщение Чудик » 05.10.2005 (Ср) 18:24

Таблица имеет пять столбцов: Data, Index, Stock, Prihod, q.
На данный момент в таблице 2600 записей.
В Grid около 120 строк.
Использую следующий код:
Код: Выделить всё
Public Sub ReadStocks()
Dim StockName As String
Dim MyDate As String
Dim ggg As String

'On Error GoTo TypeErr
MyDate = "#" & Format(Me.txtStockList.Text, "MM\/dd\/yyyy") & "#"

With Me.MSHFlexGrid1

MyCount = 0

Select Case Me.cmbStockList(0).Text

Case "Склад П1"
    For MyRow = 2 To .Rows - 1
        rsSQL = "SELECT TOP 1 * FROM Prihod WHERE Data <= " & MyDate & " And Index='" & .TextMatrix(MyRow, 0) & _
        "' order by Data DESC, q DESC;"
        Set rs = db.OpenRecordset(rsSQL)

        If rs.RecordCount = 0 Then .TextMatrix(MyRow, 7) = "+++++++++++++++": GoTo P1
           
        .TextMatrix(MyRow, 4) = Format(rs.Fields(2), "# ##0.00")
        If CVDbl(.TextMatrix(MyRow, 4)) = 0 Then .TextMatrix(MyRow, 4) = ""
P1:
        rs.Close
    Next MyRow

Case "Склад Н1"
    For MyRow = 2 To .Rows - 1
        rsSQL = "SELECT TOP 1 * FROM UhodN1 WHERE Data <= " & MyDate & " And Index='" & .TextMatrix(MyRow, 0) & _
        "' order by Data DESC, q DESC;"
        Set rs = db.OpenRecordset(rsSQL)

        If rs.RecordCount = 0 Then .TextMatrix(MyRow, 7) = "+++++++++++++++": GoTo N1
           
        .TextMatrix(MyRow, 4) = Format(rs.Fields(2), "# ##0.00")
        If CVDbl(.TextMatrix(MyRow, 4)) = 0 Then .TextMatrix(MyRow, 4) = ""
N1:
        rs.Close
    Next MyRow

Case "Склад брака"
    For MyRow = 2 To .Rows - 1
        rsSQL = "SELECT TOP 1 * FROM UhodCR WHERE Data <= " & MyDate & " And Index='" & .TextMatrix(MyRow, 0) & _
        "' order by Data DESC, q DESC;"
        Set rs = db.OpenRecordset(rsSQL)

        If rs.RecordCount = 0 Then .TextMatrix(MyRow, 7) = "+++++++++++++++": GoTo CR
           
        .TextMatrix(MyRow, 4) = Format(rs.Fields(2), "# ##0.00")
        If CVDbl(.TextMatrix(MyRow, 4)) = 0 Then .TextMatrix(MyRow, 4) = ""
CR:
        rs.Close
    Next MyRow

    End Select
   
    If rs.RecordCount = 0 Then GoTo ee
   
    .TextMatrix(MyRow, MyCol) = Format(rs.Fields(2), "# ##0.00")
    If CVDbl(.TextMatrix(MyRow, MyCol)) = 0 Then .TextMatrix(MyRow, MyCol) = ""
ee:
    rs.Close
Next MyRow

    MyCol = MyCol + 1
Loop

Set rs = Nothing
Exit Sub
End Select
.col = 1
.Sort = 1

End With

On Error Resume Next
    rs.Close
    Set rs = Nothing

End Sub


При смене названия склада в ComboBox (при такой смене происходитчтение данных из таблицы и запись их в Grid) программа зависает на некоторое время (две - три секунды). При увеличении количества записей период зависания увеличивается.
Использую DAO 3.6.
Интересно следующее: причина притормоза в DAO или в коде? Притормоз наблюдается на компе с программой. Можно ли как то избавиться от подобного зависания? Ускорить запрос …
Век живи - век учись!
www.detal-plast.narod.ru

Алексей К.
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 419
Зарегистрирован: 12.05.2004 (Ср) 9:41
Откуда: Ульяновск

Сообщение Алексей К. » 06.10.2005 (Чт) 7:05

попробуй до выполнения ReadStocks скрыть грид, а после выполнения ReadStocks покажи грид.

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 06.10.2005 (Чт) 14:29

Обработка этого свойства у меня уже использовалась, так что данный финт уже задействован. Но тормоза-то есть!
Век живи - век учись!
www.detal-plast.narod.ru

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 06.10.2005 (Чт) 14:36

по полю Data в таблице UhodCR есть индекс? если нет, то срочно ставь и по полю Index также, а еще лучше один по этим двум сразу

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 06.10.2005 (Чт) 14:54

Может я спрашу как полный идиот, но как поставить по полю индекс?
Век живи - век учись!
www.detal-plast.narod.ru

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 06.10.2005 (Чт) 15:10

Открой таблицу в конструкторе, на панеле инструментов найди кнопку "Индексы"...
Дальше я думаю разберешься.

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 06.10.2005 (Чт) 16:36

Индекс в данном случае тут много не даст.

А вот нафига столько раз Recordset-ы открывать-то????!!!!
Обойдись одним открытием.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 06.10.2005 (Чт) 16:44

может сделать ХП или prepared-command :?:

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 06.10.2005 (Чт) 17:18

Konst_One писал(а):по полю Data в таблице UhodCR есть индекс? если нет, то срочно ставь и по полю Index также, а еще лучше один по этим двум сразу

C индексами понял, но не понял как один индеск по нескольким полям поставить?

    может сделать ХП или prepared-command
Не понятно про что это?

    А вот нафига столько раз Recordset-ы открывать-то????!!!!
    Обойдись одним открытием.

У меня ведь идет перебор неповторяющихся наименований в гриде и для каждого наименования создается запрос в таблице. Так как наименование присутствует непосредственно в запросе, запрос включен в цикл. как же можно рекодсет в таком случае открыть один раз? Его же приходится обновлять при каждой смене наименования!
Век живи - век учись!
www.detal-plast.narod.ru

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 06.10.2005 (Чт) 17:20

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

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 07.10.2005 (Пт) 6:41

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


При этом он все одно кучу раз открывается.

Вообще мне сложно сказать что и для чего у него там делается по его коду, но если нужно получить кучу записей с определенными индексами, то я бы вначале построил динамический запрос навроде

Код: Выделить всё
rsSQL = "SELECT TOP 1 * FROM Prihod WHERE Data <= " & MyDate & " And Index=IN(1,12,33,...)"


Выполнил его (всего один раз достаточно) а потом искал бы в нем нужные записи методом Find (в DAO это вроде FindFirst - в Help-е глянь)...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 07.10.2005 (Пт) 14:14

меня еще смущает его TOP 1 в запросе. конечно не видя данные и структуру базы, и конкретно необходимый результат, сложно что-то посоветовать. Наверное стоит еще раз подумать над алгоритмом поиска, возможно ли обойтись одним селектом вначале, а потом искать уже в отобранном рекордсете, как тебе предложил Andrey Fedorov. Может быть даже проще сделать выборку по нужной дате при открытии формы и держать ее пока нужно искать что-то на ней.

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 07.10.2005 (Пт) 15:38

Создал индексы - скорость выполнения запросов заметно увеличилась, правда идеального варианта (по скорости) все-таки не получилось. Посижу на выходных, поковыряюсь с запросами как советовали, авось еще быстрей заработаем ....

P.S.
И все-таки хотелось бы узнать про "ХП или prepared-command" ....
Век живи - век учись!
www.detal-plast.narod.ru

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 07.10.2005 (Пт) 15:57

прямая дорога в ADO

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 16.10.2005 (Вс) 17:47

1. Не разобрался с параметрическими запросами.
Сделал так:
Dim dbf As DAO.QueryDef
Set dbf = db.QueryDefs("DataList")
dbf.Parameters("Index") = myparam
sSQL = "Select*FROM DataList Where Index= '" & myparam & "' Order by id;"
Set rs = dbf.OpenRecordset(sSQL)
For i = 1 To a - 1
myparam = .TextMatrix(i, 2)
.TextMatrix(i, 3) = rs!Name
Next i
rs.Close
результат ошибка, понимаю что не верный код, но как по другому написать, не знаю.
Хорошо бы ссылочку кто подбросил по параметрическим запросам, или подсказал, как исправить данный кусок ....
Век живи - век учись!
www.detal-plast.narod.ru

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 16.10.2005 (Вс) 18:04

Буду крайне признателен, если подскажите, как из одновременно двух таблиц грамотно сделать выборку при помощи SQL запроса! Общее поле - Index.
Век живи - век учись!
www.detal-plast.narod.ru

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 16.10.2005 (Вс) 20:39

Код: Выделить всё
select Table1.*, Table2.* from Table1 INNER JOIN Table2 ON Table1.Index=Table2.Index

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 17.10.2005 (Пн) 7:31

Я сделал так:
Код: Выделить всё
select table1*,table2* from table1,table2 where table1.index=table2.index

Работает .... В чем разница?
Век живи - век учись!
www.detal-plast.narod.ru

Rainbow
Человек-радуга
Человек-радуга
 
Сообщения: 543
Зарегистрирован: 13.05.2003 (Вт) 14:16

Сообщение Rainbow » 17.10.2005 (Пн) 17:14

Ни в чем. Два разных варианта одного и того же.
Inner Join предпочтительнее, т.к. в этой конструкции никогда не забудешь условие, по которому соединять ("ON ..."). А в твоем варианте если забыл, то результат - декартово произведение.
Учиться - значит открывать для себя то, что уже знаешь. <...> Учить - значит напоминать другим о том, что они знают это также хорошо, как и ты. <...> Лучше всего ты учишь тому, чему тебе самому больше всего надо научиться. (Р. Бах)

Чудик
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 639
Зарегистрирован: 06.07.2004 (Вт) 12:18
Откуда: г. Егорьевск

Сообщение Чудик » 17.10.2005 (Пн) 20:12

Спасибо за разъяснения!
Век живи - век учись!
www.detal-plast.narod.ru


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 2

    TopList  
cron