Ken Ismert
KIsmert at TexasSystems.com
Wed Apr 5 13:06:19 CDT 2006
David, > I couldn't see any properties in SQL2000 in the view for indexing. SQL Server Books Online has a topic "Creating an Indexed View", that covers how to create Indexed Views for SQL 2000. However, because the problem view uses a TOP and an ORDER BY clause, it can't be indexed. (As an aside, I don't recommend indexed views because their requirements are so stringent. One big gotcha: all INSERT, UPDATE and DELETE statements on tables referenced in the view must be executed with the exact same SET options as are required for indexing the view. So if you index a view, an application that doesn't use the exact SET options CANNOT modify data on any tables referenced in that view.) > The StatementNumber and InvNum fields in the underlying tables are indexed ... I don't think that underlying indexes will help much when joining against aggregate queries. > In all other cases though the join is to a table, not another view ... That may be a key, because SQL Server is likely using an index on the table to speed the join with the view. In this problem case, an aggregate view joined against an aggregate view may have to be resolved using a Cartesian product, which is very expensive. Others may have better insights to provide, but see BOL topic "Resolving Indexes on Views", and judge for yourself. Suggestion ---------- If joining tables to views gives good performance, duplicate that in your procedure. Use a new SQL Server 2000 feature called Table Variables. See "Table Variables" in BOL index. Define a table variable at the start of your proc: DECLARE @temp_cust_stmt TABLE ( CustomerID Int, -- (I'm guessing at datatypes) StatementNumber Int, StatementDate DateTime, PRIMARY KEY (CustomerID, StatementNumber) ) (I'm guessing at the Fields and Primary Key; modify it if it doesn't suit your data.) Fill the table variable: INSERT INTO @temp_cust_stmt (CustomerID, StatementNumber, StatementDate) SELECT DISTINCT CustomerID, StatementNumber, StatementDate FROM dbo.vwAgedDebtorGet (This assumes there is only one StatementDate per StatementNumber) Modify your FROM clause to join all views against your temp table: FROM @temp_cust_stmt AS t INNER JOIN dbo.vwAgedDebtorGet ON t.CustomerID = dbo.vwAgedDebtorGet.CustomerID AND t.StatementDate = dbo.vwAgedDebtorGet.StatementDate INNER JOIN dbo.vwAgedDebtorGetLastStatDate ON t.CustomerID = dbo.vwAgedDebtorGetLastStatDate.CustIDNo AND t.StatementDate = dbo.vwAgedDebtorGetLastStatDate.StatementDate (etc.) That way, you are joining all of your views against an indexed (temporary) table. That might speed things up quite a bit. BTW, could you join vwAgedDebtorGet against StatementNumber instead of StatementDate? If the data allows it, that might be a better join candidate. Hope this helps, -Ken