+3  A: 

Try in one query using 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

You will have only one query to database. The problem can be that you hit database many times and get only one (or few) row(s) per time.

Lukasz Lysik
This will only return the hits in docrec that have a match in Names and MapRec. His sample is showing a loop through ALL docrec's and finding matches for each in the names table and the maprec table.
klabranche
+3  A: 

Off the top, one thing that would help would be determining if you really need all columns.

If you don't, instead of SELECT *, select just the columns you need - that way you're not pulling as much data.

If you do, then from SQL Server Management Studio (or whatever you use to manage the SQL Server) you'll need to look at what is indexed and what isn't. The columns you tend to search on the most would be your first candidates for an index.

Addendum
Now that I've seen your edit, it may help to look at why you're doing the queries the way you are, and see if there isn't a way to consolidate it down to one query. Without more context I'd just be guessing at more optimal queries.

AnonJr
A: 

I don't know if you need the loop. If all you are doing is grabbing the records in maprec that match for docrec and then the same for the second table then you can do this without a loop using inner join syntax.

select columnlist from maprec m inner join docrec d on (m.filedyear = d.yearfield and m.volume = d.volume and m.page=d.page)

and then again for the second table...

You could also trim up your queries to return only the columns needed instead of returning all if possible. This should help performance.

To create an index by yourself in SQL Server 2005, go to the design of the table and select the Manage Indexes & Keys toolbar item.

You can use the Database Engine Tuning Advisor. You can create a trace (using sql server profiler) of your queries and then the Advisor will tell you and create the indexes needed to optimize for your query executions.

UPDATE SINCE YOUR FIRST COMMENT TO ME:

You can still do this by running the first query then the second and third without a loop as I have shown above. Here's the trick. I am thinking you need to tie the first to the second and third one hence why you did a loop.

It's been a while since I have done VB6 recordsets BUT I do recall the ability to filter the recordset once returned from the DB. So, in this case, you could keep your loop but instead of calling SQL every time in the loop you would simply filter the resulting recordset data based on the first record. You would initialize / load the second & third query before this loop to load the data. Using the syntax above that I gave will load in each of those tables the matching to the parent table (docrec).

With this, you will still only hit the DB three times but still retain the loop you need to have the parent docrec table traversed so you can do work on it AND the child tables when you do have a match.

Here's a few links on ado recordset filtering.... http://www.devguru.com/technologies/ado/QuickRef/recordset%5Ffilter.html http://msdn.microsoft.com/en-us/library/ee275540%28BTS.10%29.aspx http://www.w3schools.com/ado/prop%5Frs%5Ffilter.asp

With all this said.... I have this strange feeling that perhaps it could be solved with just a left join on your tables?

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)

this will return all DocRec records AND add all the maprec values and name values where it matches OR NULL if not.

If this fits your need it will only hit the DB once.

klabranche
I need to return every record in Docrec regardless if it has corresponding entries in the other tables or not.
read me update.... perhaps this will help
klabranche
A: 

In general looping through records is a poor idea. can you not do a set-based query that gives you everything you need in one pass?

As far as indexing consider any fields that you use in the ordering or where clauses and any fileds that arein joins. Primary keys are indexed as part of the setup of a primary ley but foreign keys are not. Often people forget that they need to index them as well.

Never use select * in a production environment. It is a poor practice. Do not ever return more data than you need.

HLGEM