我有一个访问sql数据库的VB应用程序。我认为它运行缓慢,我想也许我没有表格属性索引。我想知道你将如何创建索引?这是情况。
我的主要循环是
Select * from Docrec
Order by YearFiled,DocNumb
在这个循环中,我有两个其他的数据库命中。
Select * from Names
Where YearFiled = DocRec.YearFiled
and Volume = DocRec.Volume and Page = DocRec.Page
Order by SeqNumb
Select * from MapRec
Where FiledYear = DocRec.YearFiled
and Volume = DocRec.Volume and Page = DocRec.Page
Order by SeqNumb
希望我有道理。
答案 0 :(得分:3)
使用INNER JOIN尝试一个查询:
SELECT * FROM Doctec d
INNER JOIN Names n ON d.YearField = n.YearField AND d.Volume = n.Volume AND d.Page = n.Page
INNER JOIN MapRec m ON m.FiledYear = n.YearFiled AND m.Volume = n.Volumen and m.Page = n.Page
ORDER BY YearFiled, DocNumb
您只有一个数据库查询。问题可能是您多次命中数据库并且每次只获得一行(或几行)。
答案 1 :(得分:3)
关闭顶部,有一件事可以帮助确定您是否确实需要所有列。
如果不这样做,而不是SELECT *,只选择你需要的列 - 这样你就不会提取太多的数据。
如果您这样做,那么从SQL Server Management Studio(或您用来管理SQL Server的任何内容)中,您将需要查看索引和不索引的内容。您倾向于搜索最多的列将是您的第一个索引候选者。
<强>附录强>
现在我已经看到了您的编辑,可能有助于查看您按原样执行查询的原因,并查看是否没有办法将其合并为一个查询。如果没有更多的上下文,我只会猜测更优化的查询。
答案 2 :(得分:0)
我不知道你是否需要循环。如果您所做的只是抓取maprec中匹配docrec的记录,然后对第二个表进行相同的记录,那么您可以在没有使用内部联接语法的循环的情况下执行此操作。
select columnlist from maprec m inner join docrec d on (m.filedyear = d.yearfield and m.volume = d.volume and m.page=d.page)
然后再次进入第二张桌子......
您还可以修剪查询以仅返回所需的列,而不是尽可能返回所有列。这应该有助于提高绩效。
要在SQL Server 2005中自己创建索引,请转到表的设计并选择Manage Indexes&amp;键工具栏项。
您可以使用数据库引擎优化顾问。您可以创建查询的跟踪(使用sql server profiler),然后Advisor将告诉您并创建优化查询执行所需的索引。
自您对我的第一次评论后更新:
你仍然可以通过运行第一个查询来执行此操作,然后运行第二个和第三个查询而不使用循环,如上所示。这是诀窍。我想你需要将第一个与第二个和第三个结合起来,这就是为什么你做了一个循环。
我已经有一段时间了,因为我已经完成了VB6记录集但是我确实记得从数据库返回后过滤记录集的能力。因此,在这种情况下,您可以保留循环,但不是每次在循环中调用SQL,您只需根据第一条记录过滤生成的记录集数据。你会初始化/加载第二个&amp;在此循环之前进行第三次查询以加载数据。使用我给出的上述语法将在每个表中加载与父表(docrec)的匹配。
有了这个,你仍然只会点击数据库三次,但仍然保留了遍历父docrec表所需的循环,这样你可以在匹配时对它和子表进行操作。
以下是ado记录集过滤的一些链接.... http://www.devguru.com/technologies/ado/QuickRef/recordset_filter.html http://msdn.microsoft.com/en-us/library/ee275540(BTS.10).aspx http://www.w3schools.com/ado/prop_rs_filter.asp
所有这一切......我有这种奇怪的感觉,或许可以用你桌上的左连接来解决它?
select * from docrec d
left join maprec m on (d.YearFiled= m.FiledYear and d.Volume = m.Volume and d.Page = m.Page)
left join names n on (d.YearFiled = n.YearFiled and d.Volume = n.Volume and d.Page = n.Page)
这将返回所有DocRec记录,并将所有maprec值和名称值相加,如果不匹配则为NULL。
如果这符合您的需要,它只会击中DB一次。
答案 3 :(得分:0)
一般来说,循环记录是一个糟糕的主意。你能不能做一个基于集合的查询,在一次通过中为你提供所需的一切?
就索引而言,请考虑在排序或where子句中使用的任何字段以及任何连接的文件。主键被索引为主要ley的设置的一部分,但外键不是。通常人们忘记了他们也需要为它们编制索引。
切勿在生产环境中使用select *。这是一种糟糕的做法。永远不要返回超出您需要的数据。