VBA: запрос доступа с помощью Excel на сервере - PullRequest
1 голос
/ 14 сентября 2011

Я работаю с проектом Excel, который помогает рассчитать цену любой мебели.Первая задача - выбрать все материалы из базы данных.Это код:


Sub Material_search()
Dim cnt     As New ADODB.connection
Dim rst     As New ADODB.Recordset
Dim rcArray As Variant
Dim sSQL    As String
Dim db_path As String, db_conn As String
Dim item As String

item = Replace(TextBox1.Text, " ", "%")     ' Search word
sSQL = "Select Data, NomNr, Preke, Matas, Kaina, Tiek from VazPirkPrekes " & _
       "Where VazPirkPrekes.PirkVazID IN (SELECT VazPirkimo.PirkVazID FROM VazPirkimo Where VazPirkimo.Sandelys like '%ALIAVOS')" & _
       " and Year(VazPirkPrekes.Data)>=2011 and Preke Like '%" + item + "%' and Kaina > 0" & _
       " Order by Preke, Data Desc"
db_path = Sheets("TMP").Range("B6").value
db_conn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & db_path & ";"
cnt.Open db_conn
rst.Open sSQL, cnt, adOpenForwardOnly, adLockReadOnly
ListBox1.Clear
If Not rst.EOF Then
    rcArray = (rst.GetRows)
    rcArray = WorksheetFunction.Transpose(rcArray)
    Dim a As Variant
    With ListBox1
        .ColumnCount = 6
        .list = rcArray
        .ListIndex = -1
    End With
End If
rst.Close: Set rst = Nothing
cnt.Close: Set cnt = Nothing
Label4.Caption = UBound(ListBox1.list) + 1
End Sub

Недавно у меня возникли проблемы при запросе файла Access mdb.Проблема в том, что когда файл базы данных находится на локальном диске, поиск работает очень быстро, но когда я помещаю файл базы данных на сервер, поиск занимает в 10 раз больше времени, что недопустимо.код?или это проблема с сервером

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 14 сентября 2011

Для этого запроса ядро ​​базы данных Access должно извлечь все 190K строк из обеих таблиц.Не удивительно, что он медленный, и медлительность усугубляется, когда движок БД должен получить 2 * 190 тыс. Строк по сети.

Если TextBox1.Text содержит «foo», это оператор, который вы спрашиваетеобработчик базы данных:

Select Data, NomNr, Preke, Matas, Kaina, Tiek
from VazPirkPrekes
Where
    VazPirkPrekes.PirkVazID IN (
        SELECT VazPirkimo.PirkVazID
        FROM VazPirkimo
        Where VazPirkimo.Sandelys like '%ALIAVOS')
    and Year(VazPirkPrekes.Data)>=2011
    and Preke Like '%foo%'
    and Kaina > 0
Order by Preke, Data Desc

Механизм должен извлечь все строки 190 КБ из таблицы VazPirkimo, прежде чем он сможет определить, какие из них включают значения Sandelys, заканчивающиеся на «ALIAVOS».Если ваш критерий выбора был для значений, которые начинаются с"ALIAVOS", механизм может использовать индекс Sandelys, чтобы ограничить число строк, которые он должен извлечь из VazPirkimo.Однако, поскольку такой подход, вероятно, вам не подходит, рассмотрите возможность добавления числового поля Sandelys_group в VazPirkimo и создания индекса для Sandelys_group.Дайте всем строкам, где Sandelys заканчивается "ALIAVOS", одно и то же число Sandelys_group (1).Тогда ваше условие «IN ()» может быть таким:

SELECT VazPirkimo.PirkVazID
FROM VazPirkimo
Where VazPirkimo.Sandelys_group = 1

Индекс Sandelys_group позволит механизму БД получать только совпадающие строки, которые, будем надеяться, будут небольшим подмножеством строк 190K вТаблица.

Существуют и другие изменения, которые вы можете сделать, чтобы ускорить ваш запрос.Посмотрите на этот критерий в предложении WHERE:

Year(VazPirkPrekes.Data)>=2011

Это заставляет механизм БД извлекать все 190К строк из VazPirkPrekes, прежде чем он сможет определить, какие из них относятся к 2011 году. С индексом данных это должно бытьнамного быстрее:

VazPirkPrekes.Data >= #2011-01-01# AND VazPirkPrekes.Data < #2012-01-01#

Этот критерий WHERE будет быстрее с индексом на Kaina:

Kaina > 0

Ваш ORDER BY просит индексы на Preke и Data.

Order by Preke, Data Desc

Любые или все эти изменения могут помочь ускорить запрос, хотя я не знаю, насколько.Убийца - вот критерий, ГДЕ:

Preke Like '%foo%'

Проблема здесь аналогична проблеме со сравнением «как Санделис».Так как здесь запрашиваются строки, в которых Preke содержит «foo», а не начинается с «foo», механизм db не может использовать индекс Preke для получения только соответствующих строк.Он должен извлечь все 190K строк VazPirkPrekes, чтобы выяснить, какое совпадение.Если вы не можете использовать другой критерий для этого, вы будете ограничены в том, насколько вы можете ускорить запрос.

0 голосов
/ 15 сентября 2011

Спасибо за советы по оптимизации, но, как я уже сказал, проблема возникает только тогда, когда я размещаю файл базы данных на сервере. И не так много помощи от оптимизации. Но я подумала о другой идее.

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

Sub Database_upload()
  Application.DisplayAlerts = False
  On Error Resume Next
  Sheets("DATA_BASE").Delete
  On Error GoTo 0
  Application.DisplayAlerts = False
  Sheets.Add
  ActiveSheet.name = "DATA_BASE"
  Sheets("DATA_BASE").Visible = False: Sheets("DARBALAUKIS").activate
  Dim cnt     As New ADODB.connection
  Dim rcArray As Variant
  Dim sSQL    As String
  Dim db_path As String, db_conn As String
  Dim item As String
  Dim qQt As QueryTable
  item = ""   'search for empty blanks  
  sSQL = "Select Data, NomNr, Preke, Matas, Kaina, Tiek from VazPirkPrekes " & _
         "Where VazPirkPrekes.PirkVazID IN (SELECT VazPirkimo.PirkVazID FROM VazPirkimo Where VazPirkimo.Sandelys like '%ALIAVOS')" & _
         " and Year(VazPirkPrekes.Data)>=2011 and Preke Like '%" + item + "%' and Kaina > 0" & _
         " Order by Preke, Data Desc"

  db_path = Sheets("TMP").Range("B6").value
  db_conn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & db_path & ";"

  db_conn = "ODBC;DSN=MS Access 97 Database;"
  db_conn = db_conn & "DBQ=" & db_path
  Set qQt = Sheets("Sheet1").QueryTables.Add(connection:=db_conn, Destination:=Sheets("Sheet1").Range("A1"), Sql:=sSQL)
  qQt.Refresh BackgroundQuery:=False
End Sub

Результаты:

Программа занимает больше времени при запуске, но время поиска приемлемо - для меня проблема решена:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...