views:

37

answers:

2

I'm trying to run a set of nested or stacked queries in Microsoft Access.

As in I run Query 1
-->I use the results of Query 1 in Query 2
---->I use the results of Query 2 in Query 3
------>I use the results of Query 3 in Query 4

Query 3 takes less than 1 second to run.

-- Query 3 results -- 
PARTID  INFO
266 156-10
266 165-10
266 183-10
266 200-10
266 205-10
266 219-10
266 228-10
266 230-10
--end Query 3 results --

When I run Query 4, it takes over a minute to run. Pretty slow. So I tried making a new table (Test_Table) with the results from Query 3. I modified Query 4 to use this table rather than Query 3. Now Query 4 runs in less than 1 second.

Original Slow Query 4 code:

SELECT INVENTORYLOG.TABLEID, INVENTORYLOG.RECORDID, TIINVENTORYLOG.INFO, INVENTORYLOG.TYPEID
FROM Query3 INNER JOIN (TIINVENTORYLOG INNER JOIN INVENTORYLOG ON TIINVENTORYLOG.INVENTORYLOGID = INVENTORYLOG.ID) ON (Query3.PARTID = INVENTORYLOG.PARTID) AND (Query3.INFO = TIINVENTORYLOG.INFO)
WHERE (((INVENTORYLOG.TYPEID)<>40))
ORDER BY TIINVENTORYLOG.INFO;

Modified Fast Query 4 code:

SELECT INVENTORYLOG.TABLEID, INVENTORYLOG.RECORDID, TIINVENTORYLOG.INFO, INVENTORYLOG.TYPEID
FROM Test_Table INNER JOIN (TIINVENTORYLOG INNER JOIN INVENTORYLOG ON TIINVENTORYLOG.INVENTORYLOGID = INVENTORYLOG.ID) ON (Test_Table.info = TIINVENTORYLOG.INFO) AND (Test_Table.partid = INVENTORYLOG.PARTID)
WHERE (((INVENTORYLOG.TYPEID)<>40))
ORDER BY TIINVENTORYLOG.INFO;

Inventorylog has about 23,000 records tiinventorylog has about 18,000 records

So I guess the question is: How do I make Query 4 run quickly using Query 3 instead of my test table?

Thanks for any advice you can give.

A: 

Without knowing the first two queries, it's difficult to see right away where the issue is. However, I will say that things always slow down when you have a table joining to two other tables. (joining in a long chain is faster than joining in a circle, which is what you have here.) As you can see, you have query3 joining to both of your two tables. Perhaps something like this MIGHT work better. But it really depends on the indexing, the size of the tables, and what your other two queries are - if the two inventory tables are huge, this might actually slow it down.

So once you give a little more info I might revise this thought.

SELECT *
from (select INVENTORYLOG.TABLEID, 
            INVENTORYLOG.RECORDID, 
            TIINVENTORYLOG.INFO,
            INVENTORYLOG.TYPEID,
            INVENTORYLOG.PARTID
          from INVENTORYLOG 
          inner join TIINVENTORYLOG 
            on TIINVENTORYLOG.INVENTORYLOGID = INVENTORYLOG.ID
          where INVENTORYLOG.TYPEID<>40)a     
inner join query3 
    on query3.partid = a.partid
    and query3.info = a.info
sql_mommy
One of the main beaties of saved QueryDefs in Access is that it saves you from having a whole bunch of nested derived tables, the syntax of which can be finicky.
David-W-Fenton
That's true - it's a lot easier, but I also found a lot of problems with slow downs when I did something similar to the original poster, with one query as a source for another and then another. There's probably a way to fix it and stay within the confines of what Access does well, but I don't think there's really enough info to answer the question well at this point.
sql_mommy
Well, you guys helped me solve it in a round about way. I was going to post the code for the first 3 Queries. Queries 2,3 and 4 were all very clean with no unneeded joins or columns. Query 1 however had a few extras. To make my post clearer I cleaned Query 1 to the basics. Then for the heck of it I ran the original slow Query 4 again. Not slow anymore. Down to 1 second or less. Put the Query 1 extras back, Query 4 is slow, take the extras out, Query 4 is fast. I'd still be willing to post Queries if people are interested, but for now my problem is solved. Thanks.
greencherry
As with @greencherry's experience, I've never seen nested queries be slower unless they had unnecessary parts in them.
David-W-Fenton
makes sense, greencherry. That's why I was asking to see the other queries - cleaning up any of the early ones can greatly help when nesting like you are. Glad you solved it!
sql_mommy
Everyone looking at this should probably know about SHOWPLAN (Google "Jet SHOWPLAN" for instructions on turning it on) which will allow you to see how Jet/ACE is optimizing your query with nested queries. That could help you figure out where the bottleneck is.
David-W-Fenton
A: 

You've taken a complicated query, broken it into different parts, and created separate queries which can be reused later. All of which is good except you are taking a performance hit. I've noticed this problem in SQL Server when views are nested 3 deep or more. You rarely get something for nothing.

Now that you know what to expect from your queries and could easily test them, try combining the first two. You may have to do this in the SQL text editor. If you're lucky, you can copy the SQL from from Query1 and place it in Query 2

Select * from Query1;

becomes

Select * from (Select whatever you pasted from Query1) as Query1;

I know this can become complicated and more difficult to maintain, but if you want to improve the performance, you ususally have to give something up.

Jeff O
There should be absolutely no difference in Jet/ACE performance between the version using saved QueryDefs and the version with derived table subqueries. Well, there probably is a bit of a difference in terms of query optimization. It's possible that the optimization plans of the individual queries could conflict with the optimization plan of the version with subqueries, but I've used nested queries in all my Access apps and it's never been a performance issue, as long as they component queries are well-written.
David-W-Fenton
Whatever short-comings brought on by poorly written queries, database design and indexing are going to be compounded when you go 4 deep. At some point, you have to learn how to write a subquery.
Jeff O
You don't need to learn to write a subquery in Access for *this* purpose, though. In general, I don't use derived table subqueries in Access except where a saved QueryDef won't do the trick, i.e., the criteria change at runtime. Since I consider editing saved QueryDefs at runtime to be something to avoid, I write dynamic SQL with derived table subqueries. But that is only necessary where saved QueryDefs are not sufficient.
David-W-Fenton