Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 71 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
71
Dung lượng
877,56 KB
Nội dung
Microsoft SQL Server 2000 Programming by Example 198 between the root node and the leaf level. These intermediate pages form the nonleaf level of the index. Not every index has a nonleaf level. SQL Server tables can be organized in two ways: • As a heap, where data is stored without any specific order. • As a clustered index, where data is stored in order according to the order ofspecific key fields. In a clustered index, the actual data pages are the leaf level of the index, because the data is already in order. Clustered Indexes As explained before with the telephone directory example, SQL Server can create clustered indexes, ordering the actual data using the selected key columns as ordering criteria. Figure 6.13 shows the schema of a clustered index. You can see in the schema that the leaf level of the index is the actual data. Because the data is physically in order, there is no need for an extra layer with ordered key values plus pointers to the physical rows. Figure 6.13. A clustered index has a leaf level and a root node, plus more nonleaf levels if required. Because a clustered index physically orders the actual data, it is not possible to create more than one clustered index per table. When you create a clustered index, perhaps the keys of the index are not unique in the table. If you created a clustered nonunique index, SQL Server creates an extra hidden-integer field to uniquely identifyevery physical row. Caution Chapter 6. Optimizing Access to Data: Indexes 199 As you will see in Chapter 7, when you create a PRIMARY KEY, SQL Server creates a CLUSTERED INDEX by default, unless you specify NONCLUSTERED in the PRIMARY KEY definition. Thus, creating a PRIMARY KEY with the default settings prevents you from creating a new clustered index. Creating and Dropping Clustered Indexes As Listing 6.11 shows, to create a clustered index you must specify CLUSTERED in the CREATE INDEX statement. Listing 6.11 You Must Specify the CLUSTERED Keyword to Create a Clustered Index USE Northwind GO IF OBJECT_ID('OrderDetails') IS NOT NULL DROP TABLE OrderDetails GO Create a new table with the same structure and data as the Order Details table SELECT * INTO OrderDetails FROM [Order Details] Create a Clustered index on the new table CREATE CLUSTERED INDEX C_ORDER_DETAILS_ORDER_PRODUCT ON OrderDetails (OrderID, ProductID) To drop a CLUSTERED INDEX, you have to execute a DROP INDEX statement, as in Listing 6.12. Note that you must qualify the index name with the table name, because index names are not unique in the database. Listing 6.12 You Must Execute the DROP INDEX Statement to Remove an Index from a Table USE Northwind GO Microsoft SQL Server 2000 Programming by Example 200 DROP INDEX OrderDetails.C_ORDER_DETAILS_ORDER_PRODUCT Note If you did not execute the code from Listing 6.11 and you try to execute the code from Listing 6.12, you will get an error message because the OrderDetails table does not exist. When you drop a clustered index, the leaf level is not removed; otherwise, the data itself would be removed. Only the root node and the nonleaf levels will be deallocated. Caution You cannot specify the CLUSTERED keyword in the DROP INDEX statement. Specify the UNIQUE keyword to declare a CLUSTERED INDEX as unique, as you can see in Listing 6.13. Listing 6.13 You Must Specify the UNIQUE Keyword to Create a Unique Clustered Index USE Northwind GO CREATE UNIQUE CLUSTERED INDEX UC_ORDER_DETAILS_ORDER_PRODUCT ON OrderDetails (OrderID, ProductID) Note If you did not execute the code from Listing 6.11 and you try to execute the code from Listing 6.13, you will get an error message, because the OrderDetails table does not exist. In SQL Server 2000, every column of the key in an index can be sorted using ascending or descending order. Listing 6.14 shows an example of this new feature. Listing 6.14 You Can Specify Descending or Ascending Order for Every Column in the Index Key Chapter 6. Optimizing Access to Data: Indexes 201 USE Northwind GO CREATE INDEX C_Products_Category_Price ON Products (CategoryID ASC, UnitPrice DESC) Accessing Data Through Clustered Indexes If a table is stored as a clustered index and the Query Optimizer decides to use the clustered index to return the result, SQL Server can access data in that table in different ways: • As a Clustered Index Scan if the query doesn't restrict the data to be returned. • As a Clustered Index Seekwhen the query is restricted to a certain number of rows. Accessing Data Through a Clustered Index Scan When a Clustered Index Scan is required, it is not guaranteed that the data will be returned in order, because SQL Server could use the information stored in the IAM pages to access the data more efficiently than navigating the index. If you need results in order, you must specify an ORDER BY clause in the query. This is the case of the example of Figure 6.14. Figure 6.14. SQL Server uses a Clustered Index Scan to execute unrestricted queries. Microsoft SQL Server 2000 Programming by Example 202 Using a Clustered Index Seek to Execute Point Queries SQL Server can use aClustered Index Seek to retrieve individual rows. Figure 6.15 shows an example. Figure 6.15. SQL Server uses a Clustered Index Seek to execute restricted queries. In this example, SQL Server navigates the index from the root node to the leaf level, applying a binary search until reaching the required data. Using a Clustered Index Seek to Execute Queries with a Range Search Perhaps a more interesting use of a clustered index is to execute queries restricted to a range of values. Figure 6.16 shows an example of a range search. Figure 6.16. SQL Server uses a Clustered Index Seek to execute queries that contain a range search. Chapter 6. Optimizing Access to Data: Indexes 203 In this example, SQL Server navigates the index from the root node to the leaf level, searching for the lower limit of the range, and then continues reading from the leaf level until it reaches the upper limit of the range. Nonclustered Indexes The leaf level of a nonclustered index contains one entry for every row in the table. Each entry in the index contains the key columns and a pointer to identify the row in the table where this index entry points. As explained earlier in this chapter, if the table doesn't have a clustered index, the pointer included on every entry of the nonclustered index is a binary value. This binary value is a combination of the file number, page number, and row slot number where the original row is stored. In this way, every entry in the index is connected to the physical location of the row. If a row changes its physical location, the index pointer must be modified. This process can produce some overhead on SQL Server. If the table has a clustered index, the index entries don't point to the physical location of the rows. In this case, the pointer is the clustered key of the corresponding row. You will see later in this chapter how to access data using a nonclustered index when the data is stored as a clustered index. Creating and Dropping Nonclustered Indexes You can specifythe keyword NONCLUSTERED to create a nonclustered index using the CREATE INDEX statement. This is the default option. Listing 6.15 shows how to create a NONCLUSTERED index. Listing 6.15 You Can Specify the NONCLUSTERED Keyword to Create a Nonclustered Index Microsoft SQL Server 2000 Programming by Example 204 USE Northwind GO CREATE NONCLUSTERED INDEX C_ORDER_DETAILS_PRODUCT ON [Order Details] (ProductID) To drop a NONCLUSTERED INDEX,you have to execute a DROP INDEX statement, as in Listing 6.16. Listing 6.16 You Must Execute the DROP INDEX Statement to Remove an Index from a Table USE Northwind GO DROP INDEX [Order Details].C_ORDER_DETAILS_PRODUCT When you drop a nonclustered index, the complete index is removed, including the leaf level, the root node, and the nonleaf levels. Caution You cannot specify the NONCLUSTERED keyword in the DROP INDEX statement. Specify the UNIQUE keyword todeclare a NONCLUSTERED INDEX as unique, as you can see in Listing 6.17. Listing 6.17 You Must Specifythe UNIQUE Keyword to Create a Unique Nonclustered Index USE Northwind GO IF OBJECT_ID('NewOrders') IS NOT NULL DROP TABLE NewOrders GO SELECT * INTO NewOrders FROM Orders GO CREATE UNIQUE NONCLUSTERED INDEX UNC_ORDERS_ORDERID Chapter 6. Optimizing Access to Data: Indexes 205 ON NewOrders (OrderID) Accessing Data Through Nonclustered Indexes The way SQL Serverretrieves data through nonclustered indexes depends on the existence of a clustered index on the table. As explained earlier in this chapter, the reason for this difference in behavior is to optimize index maintenance, trying to avoid the continuous physical pointer modifications when data rows must be moved because of reordering the clustered index. Data Stored As a Heap If table data is stored as a heap, the nonclustered index is a binary structure built on top of the actual data. Figure 6.17 shows an example of index navigation. Figure 6.17. SQL Server uses a Nonclustered Index Seek to search for rows within a search condition. SQL Server searches for entries in the nonclustered index, starting from the root node and going down to the leaf level of the index. Every entry in the leaf level has a pointer to a physical row. SQL Server uses this pointer to access the page where the row is located and reads it. Data Stored As a Clustered Index Microsoft SQL Server 2000 Programming by Example 206 If table data is stored as a clustered index, it is stored in the order specified by the clustered index definition. The index is a binary structure built on top of the actual data, which in this case is the leaf level of the clustered index. Nonclustered indexes don't have a pointer to the physical position of the rows. They have as a pointer the value of the clustered index key. Figure 6.18 shows an example of nonclustered index navigation on top of a clustered index. Figure 6.18. SQL Server uses a Nonclustered Index Seek to search for rows within a search condition, and it must navigate the clustered index as well. If SQL Server decides to use a Nonclustered Index Seek to execute a query, it must follow a process similar to the one described in the preceding section, with an important difference: It also must navigate the clustered index to arrive at the physical rows. You have to consider the extra work when you use a nonclustered index on top of a clustered index. However, if you consider the number of pages to read, you will consider this solution quite efficient. The customers table could have 20,000 pages, so to execute a table scan, SQL Server will have to read 20,000 pages. Indexes don't have many levels, often less than four. The right index image should be a pyramid with a base of thousands of pages and only three or four pages high. Even if you have two pyramids to navigate, the number of pages to read is still much smaller than reading through a full table scan. Covered Queries and Index Intersection Mentioned earlier in this chapter were different ways to access data, depending on the available indexes. Let's consider the example of Listing 6.18. If you had an index on (City, CompanyName, ContactName), this index has every field required to execute the query. In this case, it is not required to access the data pages, resulting in a more efficient access method. Figures 6.19 and 6.20 show the query plan with and without this index. Chapter 6. Optimizing Access to Data: Indexes 207 Figure 6.19. SQL Server uses the index on (City, CompanyName, ContactName) to cover the query. Figure 6.20. SQL Server needs access to the data pages to execute the query if an index on (City, CompanyName, ContactName) doesn't exist. Listing 6.18 This Query Can Be Coveredby an Index on the Columns (City, CompanyName, ContactName) USE Northwind GO SELECT CompanyName, ContactName FROM Customers WHERE City = 'Madrid' In these situations, you can say that the selected index covers the query. [...]... underlying tables SQL Server 2000 Enterprise Edition can use indexed views to optimize the execution of queries that don't reference the indexed views explicitly, improving execution performance Listing 6. 34 shows how to create an index on a view Figure 6. 24 shows how SQL Server uses the view definition to access the base tables directly Figure 6.25 shows that by having an indexed view, SQL Server can avoid... as SQL Server 2000, this way of customer identification will force SQL Server to apply different conditions in sequence, one condition per attribute Perhaps it would be easy to identify every customer by a single unique value, such as 256 34, stored in a identification column, such as CustomerID In this way, to search for a customer, SQL Server will have to apply a simple condition: CustomerID = 256 34. .. can avoid accessing the base tables, reducing the amount of IO required to execute the query Figure 6. 24 When using nonindexed views, SQL Server accesses data directly from tables 220 Figure 6.25 When using indexed views, SQL Server doesn't require access to the tables Listing 6. 34 In SQL Server 2000, You Can Create Indexes on Views USE Northwind GO Create the view CREATE VIEW Customers_UK WITH SCHEMABINDING... OrderID, SQL Server can combine these two indexes to solve the query Figure 6.22 shows the query plan of this query Figure 6.22 SQL Server combines two indexes to solve the query 208 Listing 6.20 This Query Can Be Solved by an Index on OrderID and Another Index on UnitPrice USE Northwind GO SELECT OrderID, UnitPrice FROM [Order details] WHERE UnitPrice > 15 AND OrderID > 11000 Index Maintenance SQL Server. .. key length - - - Oct 23 2000 5:16PM 77 77 20 3.3189032E-2 8.0 (1 row(s) affected) All density Average Length Columns - -3 .44 82758E-2 4. 0 SupplierID 1.2987013E-2 8.0 SupplierID, ProductID 2 14 (2 row(s) affected) RANGE_HI_KEY -1 2 4 5 6 7 8 9 10 11 12 13 17 19 20 22 24 26 27 29 RANGE_ROWS -0.0 0.0 3.0 0.0 0.0 0.0 0.0 0.0... CONCAT_NULS_YIELDS_NULL ON QUOTED_IDENTIFIER ON NUMERIC_ROUNDABORT OFF Indexed Views SQL Server 2000 can create indexes on views This functionality is implemented by extensions in the CREATE VIEW and CREATE INDEX statements If a view is not indexed, it doesn't use any storage space Whenever you use the view in a Transact -SQL statement, SQL Server merges the view definition with the statement to produce a single... product you use The recommendations in this chapter refer to SQL Server 2000 If you need to implement your database on different database systems, we recommend you follow a more standard relational approach Providing a new artificial integer column to be used as a primary key has some advantages It is a short value— only 4 bytes— and SQL Server uses this value very efficiently on searching operations... indexes on tables Every INSERT, UPDATE, or DELETE operation forces SQL Server to update the index information to keep it up to date This maintenance produces some overhead on these operations Any time you insert a new row and you had a clustered index, SQL Server must search for the correct page to insert this new row If the page is full, SQL Server decides the best way to insert this row, depending on the... require Enforcing Integrity: Constraints (Declarative Data Integrity) SQL Server uses Transact -SQL structures to enforce data integrity You can create these structures during table creation or by altering the table definition after the creation of the table and even after data has been inserted into the table To enforce entity integrity, SQL Server uses PRIMARY KEY and UNIQUE constraints, UNIQUE indexes,... customers living in Toronto In this case, a table scan will produce better results SQL Server maintains distribution statistics about every index Statistic information is stored in the statblob field of the sysindexes table SQL Server samples the data to select information organized in ranges of data For every range, SQL Server stores • • • • The The The The number of rows where the key is in the specific . is the case of the example of Figure 6. 14. Figure 6. 14. SQL Server uses a Clustered Index Scan to execute unrestricted queries. Microsoft SQL Server 2000 Programming by Example 202 Using. process produces some overhead for SQL Server as well. Microsoft SQL Server 2000 Programming by Example 210 Figure 6.23. To insert a new row into a full page, SQL Server must split the page. . physical row. SQL Server uses this pointer to access the page where the row is located and reads it. Data Stored As a Clustered Index Microsoft SQL Server 2000 Programming by Example 206