Index creation and use (sqlserver 2000)

Create an index for a given table or view.
Only the owner of the table or view can create an index for the table. The owner of a table or view can create an index at any time, regardless of whether there is data in the table. You can create an index for a table or view in another database by specifying a qualified database name.

语法
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
    ON { table | view } ( column [ ASC | DESC ] [ ,...n ] )
[ WITH < index_option > [ ,...n] ]
[ ON filegroup ]

< index_option > ::=
    { PAD_INDEX |
        FILLFACTOR = fillfactor |
        IGNORE_DUP_KEY |
        DROP_EXISTING |
    STATISTICS_NORECOMPUTE |
    SORT_IN_TEMPDB 
}

Parameter
UNIQUE

Create a unique index for the table or view (two rows with the same index value are not allowed). The clustered index on the view must be a UNIQUE index.

When creating an index, if the data already exists, Microsoft? SQL Server? will check whether there are duplicate values, and this check is performed every time data is added using an INSERT or UPDATE statement. If there are duplicate key values, the CREATE INDEX statement will be canceled and an error message will be returned, giving the first duplicate value. When creating a UNIQUE index, multiple NULL values ​​are treated as copies.

If there is a unique index, then UPDATE or INSERT statements that will produce duplicate key values ​​will be rolled back and SQL Server will display an error message. This happens even if the UPDATE or INSERT statement changes many rows but only produces a duplicate value. If you enter data with a unique index and the IGNORE_DUP_KEY clause is specified, only rows that violate the UNIQUE index will fail. When processing UPDATE statements, IGNORE_DUP_KEY has no effect.

SQL Server does not allow the creation of a unique index for columns that already contain duplicate values, regardless of whether IGNORE_DUP_KEY is set. If you try to do so, SQL Server will display an error message; duplicate values ​​must be deleted before you can create a unique index for these columns.

CLUSTERED

Create an object where the physical ordering of the rows is the same as the index ordering, and the lowest level (leaf level) of the clustered index contains the actual data rows. A table or view only allows one clustered index at the same time.

Views with clustered indexes are called indexed views. You must create a unique clustered index for the view before you can define other indexes for the view.

Create a clustered index before creating any non-clustered index. The existing nonclustered index on the table is rebuilt when the clustered index is created.

If CLUSTERED is not specified, a non-clustered index is created.

 

Explanation Because by definition, the leaf level of a clustered index is the same as its data page, the use of the ON filegroup clause when creating a clustered index will actually move the table from the file used when the table was created to the new filegroup. Before creating a table or index on a specific file group, you should confirm which file groups are available and have enough space for the index. The size of the file group must be at least 1.2 times the space required for the entire table, which is very important.


NONCLUSTERED

Create an object that specifies the logical ordering of the table. For non-clustered indexes, the physical ordering of rows is independent of index ordering. The leaf level of a nonclustered index contains index rows. Each index row contains a non-clustered key value and one or more row locators (pointing to the row containing the value). If the table does not have a clustered index, the row locator is the disk address of the row. If the table has a clustered index, the row locator is the clustered index key for that row.

Each table can have up to 249 non-clustered indexes (regardless of how these non-clustered indexes are created: whether they are created implicitly using PRIMARY KEY and UNIQUE constraints, or explicitly created using CREATE INDEX). Each index can provide access to the data in a different sort order.

For indexed views, non-clustered indexes can only be created for views that have defined clustered indexes. Therefore, the row locator of the non-clustered index in the indexed view must be the clustered key of the row.

index_name

Is the index name. The index name must be unique in the table or view, but not necessarily unique in the database. Index names must follow the rules for identifiers.

table

The table containing the column to be indexed. You can choose to specify the database and table owner.

view

The name of the view to be indexed. The view must be defined with SCHEMABINDING to create an index on the view. The view definition must also be deterministic. If all expressions, WHERE, and GROUP BY clauses in the select list are deterministic, the view is also deterministic. Moreover, all key columns must be accurate. Only the non-key columns of the view may contain floating-point expressions (expressions using the float data type), and float expressions cannot be used anywhere else in the view definition.

To find a column in a deterministic view, use the COLUMNPROPERTY function (IsDeterministic property). The IsPrecise property of this function can be used to determine whether the key column is accurate.

You must create a unique clustered index for the view before you can create a nonclustered index for the view.

In SQL Server Enterprise Edition or Development Edition, the query optimizer can use indexed views to speed up the execution of queries. For the optimizer to consider the view as a replacement, it does not need to be referenced in the query.

When creating an indexed view or operating on rows in a table participating in an indexed view, there are 7 SET options that must be assigned specific values. SET options ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER, ANSI_NULLS, ANSI_PADDING and ANSI_WARNING must be ON. The SET option NUMERIC_ROUNDABORT must be OFF.

If it is different from the above settings, the data modification statements (INSERT, UPDATE, DELETE) performed on any table referenced by the indexed view will fail, and SQL Server will display an error message listing all SET options that violate the settings. In addition, for SELECT statements involving indexed views, if the value of any SET option is not the desired value, SQL Server does not consider indexed view replacement when processing the SELECT statement. In the case affected by the above SET options, this will ensure the correctness of the query results.

If the application uses a DB-Library connection, all 7 SET options on the server must be assigned the required values. (By default, OLE DB and ODBC connections have correctly set all required SET options except ARITHABORT.)

If not all of the above SET options have the required values, some operations (such as BCP, replication, or distributed queries) may not be able to perform updates to the tables participating in the indexed view. In most cases, setting ARITHABORT to ON (via user options in the server configuration options) can avoid this problem.

It is strongly recommended to set the ARITHABORT user option to ON as soon as possible after creating the first indexed view or index on a calculated column in any database on the server.

For more information on the considerations and limitations of indexed views, see the Notes section.

column

The column to which the index is applied. Specify two or more column names to create a composite index for the combined value of the specified column. List the columns to be included in the composite index in parentheses after table (in order of sorting priority).

 

Explanation Columns composed of ntext, text, or image data types cannot be designated as index columns. In addition, the view cannot include any text, ntext, or image columns, even if these columns are not referenced in the CREATE INDEX statement.


When two or more columns are best searched as a unit, or when many queries only refer to the columns specified in the index, a composite index should be used. Up to 16 columns can be combined into a composite index. All columns in the composite index must be in the same table. The maximum allowed size of the combined index value is 900 bytes. In other words, the total length of the fixed-size columns that make up the composite index cannot exceed 900 bytes. For more information about variable type columns in composite indexes, see the comments section.

[ASC | DESC]

Determine the ascending or descending sort direction of a specific index column. The default setting is ASC.

n

A placeholder that indicates that multiple columns can be specified for a specific index.

PAD_INDEX

Specify the open space on each page (node) in the middle level of the index. The PAD_INDEX option is only useful when FILLFACTOR is specified, because PAD_INDEX uses the percentage specified by FILLFACTOR. By default, given the key set on the intermediate page, SQL Server will ensure that the free space on each index page can accommodate at least one of the largest rows allowed by the index. If the percentage specified for FILLFACTOR is not large enough to fit a row, SQL Server will replace the percentage with the minimum allowed internally.

 

Note The number of rows on the intermediate index page will never be less than two rows, no matter how small the value of FILLFACTOR is.


FILLFACTOR = fillfactor

Specify how full the leaf level of each index page is during the creation of an index by SQL Server. If an index page fills up, SQL Server must take time to split the index page to make room for new rows, which requires a lot of overhead. For frequently updated tables, choosing a suitable FILLFACTOR value will obtain better update performance than choosing an inappropriate FILLFACTOR value. The original value of FILLFACTOR will be stored with the index in sysindexes.

If FILLFACTOR is specified, SQL Server will round up the number of rows to be placed on each page. For example, issuing CREATE CLUSTERED INDEX ...FILLFACTOR = 33 will create a clustered index with a FILLFACTOR of 33%. Suppose SQL Server calculates that 33% of each page space is 5.2 rows. SQL Server rounds it up so that there are 6 rows per page.

 

Note The explicit FILLFACTOR setting is only applied when the index is first created. SQL Server does not dynamically maintain a specified percentage of free space on the page.


The value of FILLFACTOR specified by the user can be from 1 to 100. If no value is specified, the default value is 0. If FILLFACTOR is set to 0, only leaf-level pages are filled. The default FILLFACTOR setting can be changed by executing sp_configure.

FILLFACTOR 100 can only be used when there are no INSERT or UPDATE statements (for example, for read-only tables). If FILLFACTOR is 100, SQL Server will create an index that is 100% full of leaf-level pages. If an INSERT or UPDATE is executed after an index with a FILLFACTOR of 100% is created, page splits will be performed on each INSERT operation and possibly each UPDATE operation.

If the FILLFACTOR value is small (other than 0), it will cause SQL Server to create a new index with incompletely populated leaf-level pages. For example, if it is known that the data contained in a table is only a small part of the data that the table will eventually contain, then when creating an index for the table, a FILLFACTOR of 10 would be a reasonable choice. A smaller FILLFACTOR value will also cause the index to take up more storage space.

The following table shows how to fill the index page when FILLFACTOR has been specified.

FILLFACTOR Intermediate page leaf level page
0 A usable item is 100% filled with
1% -99 a usable item <= FILLFACTOR% is filled with
100% a usable item is 100% filled


An available item refers to the space on the page that can hold another index item.

 

Important Use a FILLFACTOR value to create a clustered index will affect the amount of storage space occupied by the data, because SQL Server redistributes the data when creating the clustered index.


IGNORE_DUP_KEY

Control what happens when you try to insert duplicate key values ​​into a column that belongs to a unique clustered index. If IGNORE_DUP_KEY is specified for the index and an INSERT statement that creates a duplicate key is executed, SQL Server will issue a warning message and ignore the duplicate row.

If IGNORE_DUP_KEY is not specified for the index, SQL Server will issue a warning message and roll back the entire INSERT statement.

The following table shows when IGNORE_DUP_KEY can be used.

Index Type Options
gathered does not allow
a unique clustered IGNORE_DUP_KEY allowed to use
non-clustered does not allow
the only non-clustered allowed IGNORE_DUP_KEY


DROP_EXISTING

Specifies that the named pre-existing clustered index or nonclustered index should be removed and rebuilt. The specified index name must be the same as the existing index name. Because non-clustered indexes contain clustered keys, when you remove the clustered index, you must rebuild the non-clustered index. If you rebuild the clustered index, you must rebuild the non-clustered index in order to use the new key set.

When rebuilding a clustered index for a table that already has a nonclustered index (using the same or a different key set), the DROP_EXISTING clause can improve performance. The DROP_EXISTING clause replaces the process of first executing the DROP INDEX statement on the old clustered index and then executing the CREATE INDEX statement on the new clustered index. The nonclustered index only needs to be rebuilt once, and it is only needed if the keys are different.

If the key has not changed (the provided index name and column are the same as the original index), the DROP_EXISTING clause will not re-sort the data. This can be useful when indexes must be compressed.

You cannot use the DROP_EXISTING clause to convert a clustered index to a non-clustered index; however, you can change a unique clustered index to a non-unique index, and vice versa.

 

Note When executing the CREATE INDEX statement with the DROP_EXISTING clause, SQL Server assumes that the index is consistent (that is, the index is not damaged). The rows in the specified index should be sorted by the specified key referenced in the CREATE INDEX statement.


STATISTICS_NORECOMPUTE

Specify the expired index statistics will not be automatically recalculated. To restore automatic update statistics, you can execute UPDATE STATISTICS without the NORECOMPUTE clause.

 

Important If you disable the automatic recalculation of distribution statistics, it may prevent the SQL Server query optimizer from choosing the best execution plan for queries involving this table.


SORT_IN_TEMPDB

Specifies that the intermediate sort results used to generate the index will be stored in the tempdb database. If tempdb is not in the same disk set as the user database, this option may reduce the time required to create the index, but it will increase the disk space used when creating the index.

For more information, see tempdb and index creation.

ON filegroup

Create the specified index on the given filegroup. The file group must have been created by executing CREATE DATABASE or ALTER DATABASE.

Note
: When allocating space for a table or index, one extent (eight 8 KB pages) is incremented each time. Every time an extended extent is filled, another one will be allocated. If the table is very small or empty, its index will use single page allocation until 8 pages are added to the index, and then the extent allocation will be performed. To get a report on the amount of space allocated and occupied by the index, use sp_spaceused.

Creating a clustered index requires free space in the database to be approximately 1.2 times the size of the data. This space does not include the space occupied by existing tables; the data will be copied to create a clustered index, and the old non-indexed data will be deleted after the index is created. When using the DROP_EXISTING clause, the amount of space required by the clustered index is the same as the space requirements of the existing index. The additional space required may also be affected by the specified FILLFACTOR.

When creating an index in SQL Server 2000, you can use the SORT_IN_TEMPDB option to instruct the database engine to store the intermediate index sort results in tempdb. If tempdb is on a different disk set than the user database, this option may reduce the time required to create the index, but it will increase the disk space used to create the index. In addition to the space required to create indexes in the user database, tempdb must have approximately the same additional space to store intermediate sort results. For more information, see tempdb and index creation.

The CREATE INDEX statement is optimized like other queries. The SQL Server query processor can choose to scan another index instead of performing a table scan to save I/O operations. In some cases, sorting may not be necessary.

On multiprocessor computers running SQL Server Enterprise Manager and Programmer's Edition, CREATE INDEX automatically uses multiple processors to perform scanning and sorting, in the same manner as other queries. The number of processors used to execute a CREATE INDEX statement is determined by the configuration option max degree of parallelism and the current workload. If SQL Server detects that the system is busy, the concurrency of the CREATE INDEX operation will be automatically reduced before starting to execute the statement.

All file groups affected by the CREATE INDEX statement since the last file group backup must be backed up as a unit. For more information about file and filegroup backup, see BACKUP.

Backup and CREATE INDEX operations do not interfere with each other. If a backup is in progress, create an index in full logging mode, which may require additional log space.

To display reports about object indexes, execute sp_helpindex.

You can create indexes for temporary tables. When you drop the table or terminate the session, all indexes and triggers will be removed.

The variable type column in the
index allows the maximum size of the index key is 900 bytes, but SQL Server 2000 allows the creation of indexes on columns that may contain a large number of variable type columns, and the maximum size of these columns exceeds 900 bytes.

When creating an index, SQL Server checks the following conditions:

The total length of all fixed data columns participating in the index definition must be less than or equal to 900 bytes. When the index to be created consists of only fixed data columns, the total size of the fixed data columns must be less than or equal to 900 bytes. Otherwise, the index cannot be created and SQL Server will return an error.


If the index definition consists of a fixed type column and a variable type column, and the fixed data column meets the preceding conditions (less than or equal to 900 bytes), SQL Server still has to check the total size of the variable type column. If the sum of the maximum size of the variable type column and the size of the fixed data column is greater than 900 bytes, SQL Server will create an index, but will return a warning message to the user to remind the user: If subsequent inserts or updates on the variable type column If the operation causes the total size to exceed 900 bytes, the operation will fail and the user will receive a runtime error. Similarly, if the index definition consists of only variable type columns, and the maximum total size of these columns is greater than 900 bytes, SQL Server will create the index, but will return a warning message.
For more information, see Maximum Index Key.

Considerations when creating indexes on calculated columns and views
In SQL Server 2000, you can also create indexes on calculated columns and views. Creating a unique clustered index on the view can improve query performance because the view is stored in the database in the same way as the table with the clustered index.

UNIQUE or PRIMARY KEY can include calculated columns as long as all index conditions are met. Specifically, the calculated column must be deterministic, accurate, and cannot contain text, ntext, or image columns. For more information about determinism, see Deterministic Function and Non-Deterministic Function.

Creating an index on a calculated column or view may cause the previous INSERT or UPDATE operation to fail. This failure may occur when a calculated column causes an arithmetic error. For example, although the calculated column c in the following table will cause an arithmetic error, the INSERT statement is still valid:

CREATE TABLE t1 (a int, b int, c AS a/b)
GO
INSERT INTO t1 VALUES ('1', '0')
GO

Conversely, if an index is created on the computed column c after the table is created, the above INSERT statement will fail.

CREATE TABLE t1 (a int, b int, c AS a/b)
GO
CREATE UNIQUE CLUSTERED INDEX Idx1 ON t1.c
GO
INSERT INTO t1 VALUES ('1', '0')
GO

The query results obtained by using indexes on views defined by numbers or float expressions may be different from the results obtained by similar queries that do not use indexes on views. This difference may be caused by rounding errors in INSERT, DELETE, or UPDATE operations on the underlying table.

To prevent SQL Server from using indexed views, include the OPTION (EXPAND VIEWS) hint in the query. In addition, any incorrect setting of the listed options will prevent the optimizer from using the index on the view. For more information about the OPTION (EXPAND VIEWS) prompt, see SELECT.

Restrictions on
Indexed Views The SELECT statement defining an indexed view must not contain the TOP, DISTINCT, COMPUTE, HAVING, and UNION keywords. Nor can it contain subqueries.

The SELECT list must not contain asterisks (*),'table.*' wildcard list, DISTINCT, COUNT(*), COUNT(<expression>), calculated columns in the base table, and scalar aggregation.

The non-aggregated SELECT list cannot contain expressions. The aggregate SELECT list (queries containing GROUP BY) may contain SUM and COUNT_BIG(<expression>); it must contain COUNT_BIG(*). No other aggregate functions (MIN, MAX, STDEV,...) are allowed.

Complex aggregation using AVG cannot participate in the SELECT list of an indexed view. However, if the query uses such an aggregation, the optimizer will be able to use the indexed view, replacing AVG with a simple aggregation combination of SUM and COUNT_BIG.

If a column is obtained from an expression that takes a value of float data type or uses a float expression for value, it cannot be used as an index key for an indexed view or a calculated column in a table. Such columns are considered imprecise. Use the COLUMNPROPERTY function to determine whether a specific calculated column or column in a view is accurate.

Indexed views are subject to the following additional restrictions:

The creator of the index must own the table. All tables, views, and indexes must be created in the same database.


The SELECT statement that defines the indexed view must not contain views, rowset functions, in-row functions, or derived tables. The same physical table can only appear once in this statement.


In any join table, OUTER JOIN operation is not allowed.


Subqueries or CONTAINS or FREETEXT predicates are not allowed in search conditions.


If the view definition includes a GROUP BY clause, the SELECT list of the view must include all grouping columns and COUNT_BIG(*) expressions. In addition, only these columns must be included in the CREATE UNIQUE CLUSTERED INDEX clause.
The definition body of the view that can be indexed must be deterministic and accurate, which is similar to the index requirement on the calculated column. See Creating indexes on calculated columns.

The permissions of
CREATE INDEX are granted by default to the sysadmin fixed server role, db_ddladmin and db_owner fixed database roles and table owners and cannot be transferred.

Example
A. Using a simple index
The following example creates an index on the au_id column of the authors table.

SET NOCOUNT OFF
USE pubs
IF EXISTS (SELECT name FROM sysindexes
      WHERE name = 'au_id_ind')
   DROP INDEX authors.au_id_ind
GO
USE pubs
CREATE INDEX au_id_ind
   ON authors (au_id)
GO

B. Use a unique clustered index
The following example creates an index for the employeeID column of the emp_pay table and enforces uniqueness. Because the CLUSTERED clause is specified, the index will physically sort the data on the disk.

SET NOCOUNT ON
USE pubs
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
      WHERE TABLE_NAME = 'emp_pay')
   DROP TABLE emp_pay
GO
USE pubs
IF EXISTS (SELECT name FROM sysindexes
      WHERE name = 'employeeID_ind')
   DROP INDEX emp_pay.employeeID_ind
GO
USE pubs
GO
CREATE TABLE emp_pay
(
 employeeID int NOT NULL,
 base_pay money NOT NULL,
 commission decimal(2, 2) NOT NULL
)
INSERT emp_pay
   VALUES (1, 500, .10)
INSERT emp_pay
   VALUES (2, 1000, .05)
INSERT emp_pay
   VALUES (3, 800, .07)
INSERT emp_pay
   VALUES (5, 1500, .03)
INSERT emp_pay
   VALUES (9, 750, .06)
GO
SET NOCOUNT OFF
CREATE UNIQUE CLUSTERED INDEX employeeID_ind
   ON emp_pay (employeeID)
GO

C. Use a simple composite index
The following example creates an index for the orderID column and employeeID column of the order_emp table.

SET NOCOUNT ON
USE pubs
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
      WHERE TABLE_NAME = 'order_emp')
   DROP TABLE order_emp
GO
USE pubs
IF EXISTS (SELECT name FROM sysindexes
      WHERE name = 'emp_order_ind')
   DROP INDEX order_emp.emp_order_ind
GO
USE pubs
GO
CREATE TABLE order_emp
(
 orderID int IDENTITY(1000, 1),
 employeeID int NOT NULL,
 orderdate datetime NOT NULL DEFAULT GETDATE(),
 orderamount money NOT NULL
)

INSERT order_emp (employeeID, orderdate, orderamount)
   VALUES (5, '4/12/98', 315.19)
INSERT order_emp (employeeID, orderdate, orderamount)
   VALUES (5, '5/30/98', 1929.04)
INSERT order_emp (employeeID, orderdate, orderamount)
   VALUES (1, '1/03/98', 2039.82)
INSERT order_emp (employeeID, orderdate, orderamount)
   VALUES (1, '1/22/98', 445.29)
INSERT order_emp (employeeID, orderdate, orderamount)
   VALUES (4, '4/05/98', 689.39)
INSERT order_emp (employeeID, orderdate, orderamount)
   VALUES (7, '3/21/98', 1598.23)
INSERT order_emp (employeeID, orderdate, orderamount)
   VALUES (7, '3/21/98', 445.77)
INSERT order_emp (employeeID, orderdate,orderamount)
   VALUES (7, '3/22/98', 2178.98)
GO
SET NOCOUNT OFF
CREATE INDEX emp_order_ind
   ON order_emp (orderID, employeeID)

D. Use the FILLFACTOR option
The following example uses the FILLFACTOR clause and sets it to 100. A FILLFACTOR of 100 will completely fill each page. This option is only useful when you are sure that the index value in the table will never change.

SET NOCOUNT OFF
USE pubs
IF EXISTS (SELECT name FROM sysindexes
      WHERE name = 'zip_ind')
   DROP INDEX authors.zip_ind
GO
USE pubs
GO
CREATE NONCLUSTERED INDEX zip_ind
   ON authors (zip)
   WITH FILLFACTOR = 100

E. Use the
following example of IGNORE_DUP_KEY to create a unique clustered index for the emp_pay table. If a duplicate key is entered, the INSERT or UPDATE statement will be ignored.

SET NOCOUNT ON
USE pubs
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
      WHERE TABLE_NAME = 'emp_pay')
   DROP TABLE emp_pay
GO
USE pubs
IF EXISTS (SELECT name FROM sysindexes
      WHERE name = 'employeeID_ind')
   DROP INDEX emp_pay.employeeID_ind
GO
USE pubs
GO
CREATE TABLE emp_pay
(
 employeeID int NOT NULL,
 base_pay money NOT NULL,
 commission decimal(2, 2) NOT NULL
)
INSERT emp_pay
   VALUES (1, 500, .10)
INSERT emp_pay
   VALUES (2, 1000, .05)
INSERT emp_pay
   VALUES (3, 800, .07)
INSERT emp_pay
   VALUES (5, 1500, .03)
INSERT emp_pay
   VALUES (9, 750, .06)
GO
SET NOCOUNT OFF
GO
CREATE UNIQUE CLUSTERED INDEX employeeID_ind
   ON emp_pay(employeeID)
   WITH IGNORE_DUP_KEY

F. Use PAD_INDEX to create an index
The following example creates an index for the author identification number in the authors table. Without the PAD_INDEX clause, SQL Server will create leaf-level pages that are 10% filled, but the pages above the leaf level are almost completely filled. When using PAD_INDEX, the intermediate page is also filled with 10%.

 

Note If PAD_INDEX is not specified, at least two items will appear on the index page of the unique clustered index.


SET NOCOUNT OFF
USE pubs
IF EXISTS (SELECT name FROM sysindexes
      WHERE name = 'au_id_ind')
   DROP INDEX authors.au_id_ind
GO
USE pubs
CREATE INDEX au_id_ind
   ON authors (au_id)
   WITH PAD_INDEX, FILLFACTOR = 10

G. Create an index for a view
The following example will create a view and create an index for the view. Then, introduce two queries that use the indexed view.

USE Northwind
GO

--Set the options to support indexed views.
SET NUMERIC_ROUNDABORT OFF
GO
SET ANSI_PADDING,ANSI_WARNINGS,CONCAT_NULL_YIELDS_NULL,ARITHABORT,QUOTED_IDENTIFIER,ANSI_NULLS ON
GO

--Create view.
CREATE   VIEW V1
WITH   SCHEMABINDING
AS
   SELECT SUM(UnitPrice*Quantity*(1.00-Discount)) AS Revenue, OrderDate, ProductID, COUNT_BIG(*) AS COUNT
   FROM   dbo.[Order Details] od, dbo.Orders o
   WHERE   od.OrderID=o.OrderID
   GROUP BY   OrderDate, ProductID
GO

--Create index on the view.
CREATE UNIQUE CLUSTERED INDEX IV1 ON V1 (OrderDate, ProductID)
GO

--This query will use the above indexed view.
SELECT SUM(UnitPrice*Quantity*(1.00-Discount)) AS Rev, OrderDate, ProductID
FROM   dbo.[Order Details] od, dbo.Orders o
WHERE   od.OrderID=o.OrderID AND ProductID in (2, 4, 25, 13, 7, 89, 22, 34)
   AND OrderDate >= '05/01/1998'
GROUP BY OrderDate, ProductID
ORDER BY Rev DESC

--This query will use the above indexed view.
SELECT  OrderDate, SUM(UnitPrice*Quantity*(1.00-Discount)) AS Rev
FROM   dbo.[Order Details] od, dbo.Orders o
WHERE   od.OrderID=o.OrderID AND DATEPART(mm,OrderDate)= 3
   AND DATEPART(yy,OrderDate) = 1998
GROUP BY OrderDate
ORDER BY OrderDate ASC

Guess you like

Origin blog.csdn.net/geggegeda/article/details/2853108