问题
I have rephrased a previous question MS Access 2010 SQL Top N query by group performance issue (continued) as I believe the context was not clearly described before. The anwwer to my previous question did not provide the top n by group result. The rephrased question is more generic. I have now all data in one table.
Here is my situation: I have a table (Analysis) that contains products (Partnumber) of various categories (Category). Every product has a price (Value). The objective of the query is to show the 10 products with the highest price of each category The table contains 15000 records and will continue to grow.
This is the query:
SELECT
a.Location,
a.Category,
a.Partnumber
a.Value
FROM Analysis a
WHERE a.Partnumber IN (
SELECT TOP 10 aa.Partnumber
FROM Analysis aa
WHERE aa.Category = a.Category
ORDER BY aa.Value DESC
)
ORDER BY
a.Category;
Here is my question: My current query works with 1000 records in the table (respond time 3 seconds). With 15000 records the query runs endlessly long. How can I rebuild the query to significantly improve performance?
The answer to my previous question was to not use the in-list operation. But this eliminated function to give the top n records by group. The query gave the top n of all records.
回答1:
For sample data in a table called [Analysis]
ID Location Category Partnumber Value
-- --------- -------- ---------- -----
1 here cat1 part001 1
2 there cat1 part002 2
3 wherever cat1 part003 3
4 someplace cat2 part004 4
5 nowhere cat2 part005 5
6 unknown cat2 part006 6
the "ranking query"
SELECT
a1.ID,
a1.Location,
a1.Category,
a1.Partnumber,
a1.Value,
COUNT(*) AS CategoryRank
FROM
Analysis a1
INNER JOIN
Analysis a2
ON a1.Category = a2.Category
AND a1.Value <= a2.Value
GROUP BY
a1.ID,
a1.Location,
a1.Category,
a1.Partnumber,
a1.Value
returns
ID Location Category Partnumber Value CategoryRank
-- --------- -------- ---------- ----- ------------
1 here cat1 part001 1 3
2 there cat1 part002 2 2
3 wherever cat1 part003 3 1
4 someplace cat2 part004 4 3
5 nowhere cat2 part005 5 2
6 unknown cat2 part006 6 1
so if you only want the top 2 items in each category just wrap the above query in a SELECT ... WHERE
SELECT *
FROM
(
SELECT
a1.ID,
a1.Location,
a1.Category,
a1.Partnumber,
a1.Value,
COUNT(*) AS CategoryRank
FROM
Analysis a1
INNER JOIN
Analysis a2
ON a1.Category = a2.Category
AND a1.Value <= a2.Value
GROUP BY
a1.ID,
a1.Location,
a1.Category,
a1.Partnumber,
a1.Value
) AS RankingQuery
WHERE CategoryRank <= 2
ORDER BY Category, CategoryRank
to give you
ID Location Category Partnumber Value CategoryRank
-- -------- -------- ---------- ----- ------------
3 wherever cat1 part003 3 1
2 there cat1 part002 2 2
6 unknown cat2 part006 6 1
5 nowhere cat2 part005 5 2
Note: Ensure that the [Category] and [Value] fields are indexed for best performance.
来源:https://stackoverflow.com/questions/24405074/ms-access-2010-sql-top-n-query-by-group-performance-issue-continued2