我正在使用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倍的时间,这是不可接受的。
这段代码有优化吗?或者是服务器问题
提前致谢
答案 0 :(得分:1)
该查询要求Access'数据库引擎从两个表中检索所有190K行。毫不奇怪它很慢,当数据库引擎必须通过网络检索2 * 190K行时,速度会变慢。
如果TextBox1.Text包含“foo”,那么这就是您要求db引擎运行的语句:
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
引擎必须从VazPirkimo表中检索所有190K行,然后才能确定哪些行包含以“ALIAVOS”结尾的Sandelys值。如果您的选择标准是以“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上的索引将允许db引擎仅检索匹配的行,这有望成为表中190K行的一小部分。
您可以进行其他更改以加快查询速度。从WHERE子句中查看此标准:
Year(VazPirkPrekes.Data)>=2011
这迫使数据库引擎从VazPirkPrekes中检索所有190K行,然后才能确定它们中的哪一行来自2011.使用Data的索引,这应该快得多:
VazPirkPrekes.Data >= #2011-01-01# AND VazPirkPrekes.Data < #2012-01-01#
使用Kaina上的索引时,此WHERE标准会更快:
Kaina > 0
您的ORDER BY请求Preke和Data上的索引。
Order by Preke, Data Desc
任何或所有这些更改都可以帮助加快查询,但我不知道多少。杀手就是这个WHERE标准:
Preke Like '%foo%'
这里的问题类似于“Sandelys like”比较的问题。由于这要求Preke包含“foo”的行,而不是以“foo”开头,因此db引擎无法利用Preke上的索引来仅检索匹配的行。它必须检索所有190K VazPirkPrekes行以确定哪个匹配。除非您可以为此使用不同的标准,否则您将受限于加快查询的速度。
答案 1 :(得分:0)
感谢您提供优化提示,但正如我所说,只有当我将数据库文件放在服务器上时才会出现问题。并且优化没有太大帮助。但我想到了其他的想法。
搜索空白“”会返回大约40k条记录(这些记录涵盖了我需要的所有内容)。因此,我将把所有这些记录放在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
结果:
程序在启动时需要更长时间,但搜索时间是可以接受的 - 对我来说问题已经解决了:)