如何有效利用索引编写高效过程USE AdventureWorks;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--主键只用来保证数据,而聚集索引影响数据的逻辑排序
如何有效利用索引编写高效过程--
下面的语句执行计划中并没有看到排序操作,证明数据是按SalesOrderID排过序的,而且是一种双向链表
如何有效利用索引编写高效过程
SELECT TOP(10* FROM Sales.SalesOrderHeader ORDER BY SalesOrderID
如何有效利用索引编写高效过程
SELECT TOP(10* FROM Sales.SalesOrderHeader ORDER BY SalesOrderID DESC
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
SELECT TOP(10) SalesOrderID FROM Sales.SalesOrderHeader ORDER BY SalesOrderID
如何有效利用索引编写高效过程
SELECT TOP(10) SalesOrderID FROM Sales.SalesOrderHeader
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--======================================================================
如何有效利用索引编写高效过程--
查看表内数据是如何存储的
如何有效利用索引编写高效过程--
======================================================================
如何有效利用索引编写高效过程
SELECT object_name(p.object_idas tablename,i.name as indexname,
如何有效利用索引编写高效过程    rows,a.type_desc 
as page_type_desc,
如何有效利用索引编写高效过程    total_pages 
as pages,first_page
如何有效利用索引编写高效过程
FROM sys.partitions p
如何有效利用索引编写高效过程    
JOIN sys.system_internals_allocation_units a
如何有效利用索引编写高效过程        
ON p.partition_id = a.container_id
如何有效利用索引编写高效过程    
JOIN sys.indexes i 
如何有效利用索引编写高效过程        
ON p.index_id = i.index_id AND p.object_id = i.object_id
如何有效利用索引编写高效过程
WHERE p.object_id=object_id(N'Sales.SalesOrderHeader')
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--查看所含的pages字段最多的则为聚集索引叶级,其余的为别的索引页
如何有效利用索引编写高效过程--
0xA01400000100得知第一页为5280,此为聚集索引叶的第一页
如何有效利用索引编写高效过程
DBCC TRACEON(3604)
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DBCC PAGE(AdventureWorks,1,5280,3)--查看第4~7字节的值是按照SalesOrderID从小到大排列的
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--查看IX_SalesOrderHeader_CustomerID索引的第一页的第一个值是否为1
如何有效利用索引编写高效过程--
0x105200000100得到第一页为21008
如何有效利用索引编写高效过程
DBCC PAGE(AdventureWorks,1,21008,1)
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--======================================================================
如何有效利用索引编写高效过程--
行长度的限制8060
如何有效利用索引编写高效过程--
======================================================================
如何有效利用索引编写高效过程
USE tempdb;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
IF OBJECT_ID(N'bigrows',N'U'IS NOT NULL
如何有效利用索引编写高效过程    
DROP TABLE dbo.bigrows
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
CREATE TABLE dbo.bigrows
如何有效利用索引编写高效过程(
如何有效利用索引编写高效过程    a 
char(3000),
如何有效利用索引编写高效过程    b 
char(3000),
如何有效利用索引编写高效过程    c 
char(2000),
如何有效利用索引编写高效过程    d 
char(60)
如何有效利用索引编写高效过程)
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
INSERT INTO dbo.bigrows
如何有效利用索引编写高效过程    
SELECT REPLICATE('a',3000),REPLICATE('b',3000),
如何有效利用索引编写高效过程            
REPLICATE('c',2000),REPLICATE('d',6)
如何有效利用索引编写高效过程
--2005使用行溢出数据突破了変长列的限制,但这样会增加I/O操作。
如何有效利用索引编写高效过程
IF OBJECT_ID(N'bigrows',N'U'IS NOT NULL
如何有效利用索引编写高效过程    
DROP TABLE dbo.bigrows
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
CREATE TABLE dbo.bigrows
如何有效利用索引编写高效过程(
如何有效利用索引编写高效过程    a 
varchar(3000),
如何有效利用索引编写高效过程    b 
varchar(3000),
如何有效利用索引编写高效过程    c 
varchar(3000),
如何有效利用索引编写高效过程    d 
varchar(3000)
如何有效利用索引编写高效过程)
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
INSERT INTO dbo.bigrows
如何有效利用索引编写高效过程    
SELECT REPLICATE('a',3000),REPLICATE('b',3000),
如何有效利用索引编写高效过程            
REPLICATE('c',3000),REPLICATE('d',3000)
如何有效利用索引编写高效过程
SELECT object_name(object_idas name,
如何有效利用索引编写高效过程    partition_id,partition_number 
as pnum,rows,
如何有效利用索引编写高效过程    allocation_unit_id 
as au_id,type_desc as page_type,total_pages as pages
如何有效利用索引编写高效过程
FROM sys.partitions p    
如何有效利用索引编写高效过程    
JOIN sys.allocation_units a
如何有效利用索引编写高效过程        
ON p.partition_id = a.container_id
如何有效利用索引编写高效过程
WHERE object_id = object_id(N'dbo.bigrows');
如何有效利用索引编写高效过程
--======================================================================
如何有效利用索引编写高效过程--
非聚集索引通过聚集索引进行查找
如何有效利用索引编写高效过程--
======================================================================
如何有效利用索引编写高效过程--
SQL2005新增用于查看表中各索引的统计的动态函数
如何有效利用索引编写高效过程
SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(N'AdventureWorks'), OBJECT_ID(N'Sales.SalesOrderHeader'), NULLNULL , 'DETAILED');
如何有效利用索引编写高效过程
--索引的深度
如何有效利用索引编写高效过程
SELECT INDEXPROPERTY(object_ID('Sales.SalesOrderHeader'),N'PK_SalesOrderHeader_SalesOrderID','IndexDepth')
如何有效利用索引编写高效过程
SELECT INDEXPROPERTY(object_ID('Sales.SalesOrderHeader'),N'AK_SalesOrderHeader_SalesOrderNumber','IndexDepth')
如何有效利用索引编写高效过程
--聚集索引查找,因为索引的深度为3,所以此时逻辑读为3
如何有效利用索引编写高效过程
SELECT * FROM Sales.SalesOrderHeader WHERE SalesOrderID=43659
如何有效利用索引编写高效过程
--非聚集索引通过聚集索引进行查找(逻辑读有5次,因为聚集为3,非聚集为2)
如何有效利用索引编写高效过程
SELECT * FROM Sales.SalesOrderHeader WHERE SalesOrderNumber=N'SO45283'
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--======================================================================
如何有效利用索引编写高效过程--
复合索引测试
如何有效利用索引编写高效过程--
======================================================================
如何有效利用索引编写高效过程
BEGIN TRANSACTION
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DROP INDEX IX_SalesOrderHeader_CustomerID ON Sales.SalesOrderHeader
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
CREATE NONCLUSTERED INDEX IX_SalesOrderHeader_CustomerID ON Sales.SalesOrderHeader
如何有效利用索引编写高效过程    (
如何有效利用索引编写高效过程    CustomerID,
如何有效利用索引编写高效过程    CreditCardID
如何有效利用索引编写高效过程    ) 
WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ONON [PRIMARY]
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
COMMIT
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
UPDATE STATISTICS Sales.SalesOrderHeader IX_SalesOrderHeader_CustomerID
如何有效利用索引编写高效过程
--查看此索引的统计信息
如何有效利用索引编写高效过程
DBCC SHOW_STATISTICS('Sales.SalesOrderHeader',IX_SalesOrderHeader_CustomerID)
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
SELECT COUNT(*--EQ_ROWS等于上限值的个数
如何有效利用索引编写高效过程
FROM Sales.SalesOrderHeader
如何有效利用索引编写高效过程
WHERE CustomerID=1
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
SELECT COUNT(*--RANGE_ROWS此范围内不包括边界的记录数
如何有效利用索引编写高效过程
FROM Sales.SalesOrderHeader
如何有效利用索引编写高效过程
WHERE CustomerID>1 AND CustomerID<19
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
SELECT  COUNT(DISTINCT CustomerID)--DISTINCT_RANGE_ROWS 此范围内不包括边界的不同记录数
如何有效利用索引编写高效过程
FROM Sales.SalesOrderHeader
如何有效利用索引编写高效过程
WHERE CustomerID>1 AND CustomerID<19
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
SELECT  1.0*COUNT(*)/COUNT(DISTINCT CustomerID)--AVG_RANGE_ROWS 数据分布程度
如何有效利用索引编写高效过程
FROM Sales.SalesOrderHeader
如何有效利用索引编写高效过程
WHERE CustomerID>1 AND CustomerID<19
如何有效利用索引编写高效过程
--查看Sales.SalesOrderHeader表中索引信息
如何有效利用索引编写高效过程
SELECT * FROM 
如何有效利用索引编写高效过程sys.dm_db_index_physical_stats(
DB_ID(N'AdventureWorks'), OBJECT_ID(N'Sales.SalesOrderHeader'), NULLNULL , 'DETAILED');
如何有效利用索引编写高效过程
--IX_SalesOrderHeader_CustomerID的索引编号为5深度为2,叶级有71个页面,根叶1页
如何有效利用索引编写高效过程
SELECT QUOTENAME(name)
如何有效利用索引编写高效过程
FROM sys.indexes
如何有效利用索引编写高效过程
WHERE  object_id = 722101613 AND index_id = 5;
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
DBCC DROPCLEANBUFFERS;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DBCC FREEPROCCACHE;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--非聚集索引查找+键值查找(逻辑读为8,非聚集索引查找2页加每个值一次聚集索引查找)
如何有效利用索引编写高效过程
SELECT * FROM Sales.SalesOrderHeader WHERE CustomerID=19965
如何有效利用索引编写高效过程
--非聚集索引扫描+键值查找(因此使用复合索引除第一个字段外,不会进行索引查找)
如何有效利用索引编写高效过程
SELECT * FROM Sales.SalesOrderHeader WHERE CreditCardID=15466
如何有效利用索引编写高效过程
--覆盖索引查找(逻辑读为2,说明只在非聚集索引中查找到了所需的数据)
如何有效利用索引编写高效过程
SELECT SalesOrderID,CreditCardID FROM Sales.SalesOrderHeader
如何有效利用索引编写高效过程
WHERE CustomerID=19965
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--作为查询条件的字段会自动创建统计
如何有效利用索引编写高效过程
SELECT * FROM Production.Location WHERE ModifiedDate>'20070101'
如何有效利用索引编写高效过程
--所有自动创建的统计
如何有效利用索引编写高效过程
SELECT m.name+'.'+object_name(s.object_idas [table],s.name as [statistics],c.name as [column]
如何有效利用索引编写高效过程
FROM sys.stats s
如何有效利用索引编写高效过程    
join sys.stats_columns sc
如何有效利用索引编写高效过程        
on s.stats_id = sc.stats_id and s.object_id = sc.object_id
如何有效利用索引编写高效过程    
join sys.columns c 
如何有效利用索引编写高效过程        
on sc.column_id = c.column_id and c.object_id = sc.object_id
如何有效利用索引编写高效过程    
join sys.objects o 
如何有效利用索引编写高效过程        
on s.object_id = o.object_id
如何有效利用索引编写高效过程    
join sys.schemas m
如何有效利用索引编写高效过程        
on m.schema_id = o.schema_id
如何有效利用索引编写高效过程
where s.auto_created=1 and o.type='U'
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
SELECT object_name(id),name,statblob--统计信息二进制大型对象(BLOB),仅内部使用,返回NULL.
如何有效利用索引编写高效过程
FROM sys.sysindexes
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--SELECT * FROM sys.stats_columns
如何有效利用索引编写高效过程--
====================================================================================
如何有效利用索引编写高效过程--
选择度过低而无法有效利用索引查找而选择表扫描,查询2004-7-01之后的订单
如何有效利用索引编写高效过程--
====================================================================================
如何有效利用索引编写高效过程
USE AdventureWorks;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
BEGIN TRANSACTION
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DROP INDEX IX_OrderDate ON Sales.SalesOrderHeader
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
CREATE NONCLUSTERED INDEX IX_OrderDate ON Sales.SalesOrderHeader
如何有效利用索引编写高效过程    (
如何有效利用索引编写高效过程    OrderDate
如何有效利用索引编写高效过程    ) 
WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ONON [PRIMARY]
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
COMMIT
如何有效利用索引编写高效过程
DBCC DROPCLEANBUFFERS;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DBCC FREEPROCCACHE;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--分别使用2004-7-01低选择度与2004-7-26高选择度比较两种查询的性能差异
如何有效利用索引编写高效过程
SELECT SalesOrderID,OrderDate,Status,CustomerID,TaxAmt,TotalDue
如何有效利用索引编写高效过程
FROM Sales.SalesOrderHeader
如何有效利用索引编写高效过程
WHERE OrderDate>'2004-7-01'
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--首先在非聚焦索引叶级中扫描获得最大及最小的订单号,由于此时表扫描只是在叶级所以I/O操作会明显减少
如何有效利用索引编写高效过程
DECLARE @min int,
如何有效利用索引编写高效过程        
@max int
如何有效利用索引编写高效过程
SELECT @min=MIN(SalesOrderID),@max=MAX(SalesOrderID) 
如何有效利用索引编写高效过程
FROM Sales.SalesOrderHeader
如何有效利用索引编写高效过程
WHERE OrderDate>'2004-7-01'
如何有效利用索引编写高效过程
--使用聚焦索引
如何有效利用索引编写高效过程
SELECT SalesOrderID,OrderDate,Status,CustomerID,TaxAmt,TotalDue
如何有效利用索引编写高效过程
FROM Sales.SalesOrderHeader
如何有效利用索引编写高效过程
WHERE SalesOrderID BETWEEN @min AND @max
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--================================================
如何有效利用索引编写高效过程--
什么是查询参数规范SARGS
如何有效利用索引编写高效过程--
================================================
如何有效利用索引编写高效过程--
1、不要对字段做运算
如何有效利用索引编写高效过程
SELECT * FROM Sales.SalesOrderHeader WHERE CustomerID+1=2
如何有效利用索引编写高效过程
SELECT * FROM Sales.SalesOrderHeader WHERE CustomerID=1
如何有效利用索引编写高效过程
--2、不要对字段使用函数(数学函数、日期函数、字符串函数等)
如何有效利用索引编写高效过程
SELECT * FROM Sales.SalesOrderHeader WHERE ABS(SalesOrderID-44659)<1
如何有效利用索引编写高效过程
SELECT * FROM Sales.SalesOrderHeader WHERE SalesOrderID<44660 AND SalesOrderID>44658
如何有效利用索引编写高效过程
--3、不要使用负向查询(NOT、!=、<>、!>、!<、NOT EXISTS、NOT IN)
如何有效利用索引编写高效过程
SELECT * FROM Sales.SalesOrderDetail WHERE OrderQty!=1
如何有效利用索引编写高效过程
SELECT * FROM Sales.SalesOrderDetail WHERE OrderQty>1 OR OrderQty<1
如何有效利用索引编写高效过程
--4、小心使用OR(虽然有聚集索引但是因Status无索引可用只能进行表扫描)
如何有效利用索引编写高效过程
SELECT * FROM Sales.SalesOrderHeader WHERE SalesOrderID=43659 OR [Status]=1
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--================================================================================
如何有效利用索引编写高效过程--
三种联结(嵌套循环、合并联结、哈稀联结),所占用的资源依次增加,SQL优先选用嵌套循环
如何有效利用索引编写高效过程--
================================================================================
如何有效利用索引编写高效过程--
1、嵌套循环(外表、内表),记录少的表作为外表,在内表中根据每个联结字段的值进行
如何有效利用索引编写高效过程--
循环,只有在外表数据量较少时使用
如何有效利用索引编写高效过程
SELECT *
如何有效利用索引编写高效过程
FROM Sales.SalesOrderDetail D JOIN Sales.SalesOrderHeader O
如何有效利用索引编写高效过程    
ON D.SalesOrderID = O.SalesOrderID
如何有效利用索引编写高效过程
WHERE O.SalesOrderID BETWEEN 43659 AND 43665
如何有效利用索引编写高效过程
--2、合并联结的算法前提是字段已排序
如何有效利用索引编写高效过程
SELECT *
如何有效利用索引编写高效过程
FROM Sales.SalesOrderDetail D JOIN Sales.SalesOrderHeader O
如何有效利用索引编写高效过程    
ON D.SalesOrderID = O.SalesOrderID
如何有效利用索引编写高效过程
WHERE O.SalesOrderID BETWEEN 43659 AND 54000
如何有效利用索引编写高效过程
--3、哈稀联结(在要联结的字段上无可用索引时使用此连接算法)
如何有效利用索引编写高效过程
IF OBJECT_ID(N'SumPrice',N'U'IS NOT NULL
如何有效利用索引编写高效过程    
DROP TABLE SumPrice
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
SELECT O.SalesOrderID,YEAR(O.OrderDate)+MONTH(O.OrderDate) AS Date,CAST(SUM(D.OrderQty*D.UnitPrice*(1-D.UnitPriceDiscount)) AS decimal(18,2)) AS Price
如何有效利用索引编写高效过程
INTO SumPrice
如何有效利用索引编写高效过程
FROM 
如何有效利用索引编写高效过程    Sales.SalesOrderDetail D 
如何有效利用索引编写高效过程        
JOIN 
如何有效利用索引编写高效过程    Sales.SalesOrderHeader O
如何有效利用索引编写高效过程        
ON D.SalesOrderID=O.SalesOrderID
如何有效利用索引编写高效过程
GROUP BY O.SalesOrderID,O.OrderDate
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
SELECT O.SalesOrderID,O.
如何有效利用索引编写高效过程
FROM SumPrice D JOIN Sales.SalesOrderHeader O
如何有效利用索引编写高效过程    
ON D.SalesOrderID = O.SalesOrderID
如何有效利用索引编写高效过程
WHERE O.SalesOrderID BETWEEN 43659 AND 54000
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--==========================================================================================
如何有效利用索引编写高效过程--
代替LEFT JOIN的方法
如何有效利用索引编写高效过程--
为了防止在查询中出现LEFT操作,在设计数据库时应尽量避免关联表中不一致的情况出现
如何有效利用索引编写高效过程--
比如产品的类别和具体产品的对应关系中,可在类别加入一个无类别的记录以对应不知是何类别的产品
如何有效利用索引编写高效过程--
==========================================================================================
如何有效利用索引编写高效过程
BEGIN TRANSACTION
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DROP INDEX IX_SalesOrderHeader_CustomerID ON Sales.SalesOrderHeader
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
CREATE NONCLUSTERED INDEX IX_SalesOrderHeader_CustomerID ON Sales.SalesOrderHeader
如何有效利用索引编写高效过程    (
如何有效利用索引编写高效过程    CustomerID
如何有效利用索引编写高效过程    ) 
WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ONON [PRIMARY]
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
COMMIT
如何有效利用索引编写高效过程
DBCC FLUSHPROCINDB(8);
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DBCC DROPCLEANBUFFERS;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--1、查询所有客户的总订单数量
如何有效利用索引编写高效过程
SELECT C.CustomerID,COALESCE(SUM(OrderQty),0AS Quantity
如何有效利用索引编写高效过程
FROM Sales.Customer C LEFT JOIN            
如何有效利用索引编写高效过程    (    Sales.SalesOrderHeader O 
如何有效利用索引编写高效过程        
JOIN Sales.SalesOrderDetail D ON O.SalesOrderID=D.SalesOrderID
如何有效利用索引编写高效过程    ) 
ON C.CustomerID=O.CustomerID
如何有效利用索引编写高效过程
GROUP BY C.CustomerID
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--2、替代的查询方式
如何有效利用索引编写高效过程
DECLARE @CustomerInfo table
如何有效利用索引编写高效过程(
如何有效利用索引编写高效过程    CustomerID    
int            not null,
如何有效利用索引编写高效过程    Quantity    
smallint    not null
如何有效利用索引编写高效过程)
如何有效利用索引编写高效过程
INSERT INTO @CustomerInfo
如何有效利用索引编写高效过程
SELECT CustomerID,0
如何有效利用索引编写高效过程
FROM Sales.Customer;
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
WITH SumQuantity AS
如何有效利用索引编写高效过程(
如何有效利用索引编写高效过程    
SELECT O.CustomerID,COALESCE(SUM(OrderQty),0AS Quantity
如何有效利用索引编写高效过程    
FROM Sales.SalesOrderHeader O 
如何有效利用索引编写高效过程    
JOIN Sales.SalesOrderDetail D ON O.SalesOrderID=D.SalesOrderID
如何有效利用索引编写高效过程    
GROUP BY O.CustomerID
如何有效利用索引编写高效过程)
如何有效利用索引编写高效过程
UPDATE @CustomerInfo
如何有效利用索引编写高效过程
SET C.Quantity=S.Quantity
如何有效利用索引编写高效过程
FROM @CustomerInfo C JOIN SumQuantity S
如何有效利用索引编写高效过程    
ON S.CustomerID=C.CustomerID;
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
SELECT * FROM @CustomerInfo;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--==========================================================================================
如何有效利用索引编写高效过程--
控制表之间的联结
如何有效利用索引编写高效过程--
==========================================================================================
如何有效利用索引编写高效过程
USE Northwind;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
SELECT DISTINCT C.CompanyName AS customer, S.CompanyName AS supplier
如何有效利用索引编写高效过程
FROM dbo.Customers AS C
如何有效利用索引编写高效过程  
LEFT OUTER JOIN dbo.Orders AS O
如何有效利用索引编写高效过程    
ON O.CustomerID = C.CustomerID
如何有效利用索引编写高效过程  
LEFT OUTER JOIN dbo.[Order Details] AS OD
如何有效利用索引编写高效过程    
ON OD.OrderID = O.OrderID
如何有效利用索引编写高效过程  
LEFT OUTER JOIN dbo.Products AS P
如何有效利用索引编写高效过程    
ON P.ProductID = OD.ProductID
如何有效利用索引编写高效过程  
LEFT OUTER JOIN dbo.Suppliers AS S
如何有效利用索引编写高效过程    
ON S.SupplierID = P.SupplierID
如何有效利用索引编写高效过程
--OPTION(FORCE ORDER);
如何有效利用索引编写高效过程--
上面的查询过多的使用外联结,可使用下面的方式替换
如何有效利用索引编写高效过程
SELECT DISTINCT C.CompanyName AS customer, S.CompanyName AS supplier
如何有效利用索引编写高效过程
FROM dbo.Orders AS O
如何有效利用索引编写高效过程  
JOIN dbo.[Order Details] AS OD
如何有效利用索引编写高效过程    
ON OD.OrderID = O.OrderID
如何有效利用索引编写高效过程  
JOIN dbo.Products AS P
如何有效利用索引编写高效过程    
ON P.ProductID = OD.ProductID
如何有效利用索引编写高效过程  
JOIN dbo.Suppliers AS S
如何有效利用索引编写高效过程    
ON S.SupplierID = P.SupplierID
如何有效利用索引编写高效过程  
RIGHT OUTER JOIN dbo.Customers AS C
如何有效利用索引编写高效过程    
ON O.CustomerID = C.CustomerID;
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
SELECT DISTINCT C.CompanyName AS customer, S.CompanyName AS supplier
如何有效利用索引编写高效过程
FROM dbo.Customers AS C
如何有效利用索引编写高效过程  
LEFT OUTER JOIN
如何有效利用索引编写高效过程    (dbo.Orders 
AS O
如何有效利用索引编写高效过程       
JOIN dbo.[Order Details] AS OD
如何有效利用索引编写高效过程         
ON OD.OrderID = O.OrderID
如何有效利用索引编写高效过程       
JOIN dbo.Products AS P
如何有效利用索引编写高效过程         
ON P.ProductID = OD.ProductID
如何有效利用索引编写高效过程       
JOIN dbo.Suppliers AS S
如何有效利用索引编写高效过程         
ON S.SupplierID = P.SupplierID)
如何有效利用索引编写高效过程      
ON O.CustomerID = C.CustomerID;
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--============================================================
如何有效利用索引编写高效过程--
存储过程相关
如何有效利用索引编写高效过程--
============================================================
如何有效利用索引编写高效过程
USE Northwind;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--***********************************************************
如何有效利用索引编写高效过程--
1、计划缓存重用造成的无效查询计划
如何有效利用索引编写高效过程--
造成上述问题的原因是因为SQLServer为了节省编译的开销会优先考虑使用缓存的计划
如何有效利用索引编写高效过程--
2000下只能使用过程级重新编译,2005下提供了语句级重新编译的特性。从而避免了编译
如何有效利用索引编写高效过程--
整个过程的开销
如何有效利用索引编写高效过程
IF OBJECT_ID(N'dbo.usp_GetOrders',N'P'IS NOT NULL
如何有效利用索引编写高效过程  
DROP PROC dbo.usp_GetOrders;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
CREATE PROC dbo.usp_GetOrders
如何有效利用索引编写高效过程  
@odate AS DATETIME
如何有效利用索引编写高效过程
AS
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
SELECT c.CustomerID, c.CompanyName,
如何有效利用索引编写高效过程    o.EmployeeID, o.OrderID, o.OrderDate
如何有效利用索引编写高效过程
FROM dbo.Orders o
如何有效利用索引编写高效过程    
join dbo.Customers c
如何有效利用索引编写高效过程        
on o.CustomerID = c.CustomerID
如何有效利用索引编写高效过程
WHERE OrderDate >= @odate;
如何有效利用索引编写高效过程
--OPTION(RECOMPILE);
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--选择度高的测试
如何有效利用索引编写高效过程
EXEC dbo.usp_GetOrders '19980506';
如何有效利用索引编写高效过程
--选择度低的测试
如何有效利用索引编写高效过程
EXEC dbo.usp_GetOrders '19960101';
如何有效利用索引编写高效过程
--查看缓存计划
如何有效利用索引编写高效过程
SELECT *
如何有效利用索引编写高效过程
FROM sys.syscacheobjects
如何有效利用索引编写高效过程
WHERE sql NOT LIKE '%cache%'
如何有效利用索引编写高效过程  
AND sql LIKE '%usp_GetOrders%';
如何有效利用索引编写高效过程
--清除缓存计划
如何有效利用索引编写高效过程
DBCC FREEPROCCACHE;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--***********************************************************
如何有效利用索引编写高效过程--
2、参数嗅探测
如何有效利用索引编写高效过程--
以当前日期插入一条记录,高选择度查询
如何有效利用索引编写高效过程
INSERT INTO dbo.Orders(OrderDate, CustomerID, EmployeeID) VALUES(GETDATE(), N'ALFKI'1);
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
ALTER PROC dbo.usp_GetOrders
如何有效利用索引编写高效过程  
@d AS INT = 0
如何有效利用索引编写高效过程
AS
如何有效利用索引编写高效过程
DECLARE @odate AS DATETIME;
如何有效利用索引编写高效过程
SET @odate = DATEADD(day-@dCONVERT(VARCHAR(8), GETDATE(), 112));
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
SELECT OrderID, CustomerID, EmployeeID, OrderDate
如何有效利用索引编写高效过程
FROM dbo.Orders
如何有效利用索引编写高效过程
WHERE OrderDate >= @odate;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--查看表dbo.Orders空间情况
如何有效利用索引编写高效过程
SELECT * FROM 
如何有效利用索引编写高效过程sys.dm_db_index_physical_stats(
DB_ID(N'Northwind'), OBJECT_ID(N'dbo.Orders'), NULLNULL , 'DETAILED');
如何有效利用索引编写高效过程
--此时虽然选择度高,但是因为在过程编译时优化器无法根据参数进行最优化
如何有效利用索引编写高效过程
EXEC dbo.usp_GetOrders;
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--使用聚集索引代替非聚集索引进行查询的参数嗅探测试
如何有效利用索引编写高效过程
USE AdventureWorks;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
IF OBJECT_ID(N'dbo.GetCutomerOrderByDate',N'P'IS NOT NULL
如何有效利用索引编写高效过程  
DROP PROC dbo.GetCutomerOrderByDate;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
CREATE PROCEDURE dbo.GetCutomerOrderByDate
如何有效利用索引编写高效过程    
@start datetime
如何有效利用索引编写高效过程
AS
如何有效利用索引编写高效过程
BEGIN
如何有效利用索引编写高效过程    
SET NOCOUNT ON;
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程    
DECLARE @min int,
如何有效利用索引编写高效过程        
@max int
如何有效利用索引编写高效过程    
SELECT @min=MIN(SalesOrderID),@max=MAX(SalesOrderID) 
如何有效利用索引编写高效过程    
FROM Sales.SalesOrderHeader
如何有效利用索引编写高效过程    
WHERE OrderDate>@start
如何有效利用索引编写高效过程    
SELECT SalesOrderID,OrderDate,Status,CustomerID,TaxAmt,TotalDue
如何有效利用索引编写高效过程    
FROM Sales.SalesOrderHeader
如何有效利用索引编写高效过程    
WHERE SalesOrderID BETWEEN @min AND @max
如何有效利用索引编写高效过程
END
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DBCC FREEPROCCACHE;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--低选择度测试
如何有效利用索引编写高效过程
EXEC dbo.GetCutomerOrderByDate '2004-5-01'
如何有效利用索引编写高效过程
--高选择度测试
如何有效利用索引编写高效过程
EXEC dbo.GetCutomerOrderByDate '2004-7-26'
如何有效利用索引编写高效过程
--缓存计划
如何有效利用索引编写高效过程
SELECT *
如何有效利用索引编写高效过程
FROM sys.syscacheobjects
如何有效利用索引编写高效过程
WHERE sql NOT LIKE '%cache%'
如何有效利用索引编写高效过程  
AND sql LIKE '%GetCutomerOrderByDate%';
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--***********************************************************
如何有效利用索引编写高效过程--
3、Execute/sp_executesql
如何有效利用索引编写高效过程
USE Northwind;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DBCC FREEPROCCACHE;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--
如何有效利用索引编写高效过程
DECLARE @i        AS INT;
如何有效利用索引编写高效过程
DECLARE @sql    AS VARCHAR(52);
如何有效利用索引编写高效过程
SET @i = 10248;
如何有效利用索引编写高效过程
WHILE @i<10252
如何有效利用索引编写高效过程
BEGIN
如何有效利用索引编写高效过程    
SET @sql = 'SELECT * FROM dbo.Orders WHERE OrderID = '
如何有效利用索引编写高效过程      
+ CAST(@i AS VARCHAR(10)) + N';';
如何有效利用索引编写高效过程    
EXEC(@sql);
如何有效利用索引编写高效过程    
SET @i=@i+1
如何有效利用索引编写高效过程
END
如何有效利用索引编写高效过程
--查看缓存计划,可以看到除了参数化计划外还为每个不同的值保存一个缓存计划
如何有效利用索引编写高效过程
SELECT cacheobjtype, objtype, usecounts, sql
如何有效利用索引编写高效过程
FROM sys.syscacheobjects
如何有效利用索引编写高效过程
WHERE sql NOT LIKE '%cache%'
如何有效利用索引编写高效过程  
AND sql NOT LIKE '%sys.%';
如何有效利用索引编写高效过程
--存储过程中调用同样存在上面的问题,为每个参数分配一个缓存计划
如何有效利用索引编写高效过程
IF OBJECT_ID(N'dbo.GetOrderByID',N'P'IS NOT NULL
如何有效利用索引编写高效过程  
DROP PROC dbo.GetOrderByID;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
CREATE PROCEDURE dbo.GetOrderByID
如何有效利用索引编写高效过程
@i AS INT
如何有效利用索引编写高效过程
AS
如何有效利用索引编写高效过程
BEGIN
如何有效利用索引编写高效过程    
SET NOCOUNT ON;
如何有效利用索引编写高效过程    
DECLARE @sql AS VARCHAR(52);
如何有效利用索引编写高效过程    
SET @sql = 'SELECT * FROM dbo.Orders WHERE OrderID = '
如何有效利用索引编写高效过程      
+ CAST(@i AS VARCHAR(10)) + N';';
如何有效利用索引编写高效过程    
EXEC(@sql);
如何有效利用索引编写高效过程
END
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DECLARE @i        AS INT;
如何有效利用索引编写高效过程
SET @i = 10248;
如何有效利用索引编写高效过程
WHILE @i<10252
如何有效利用索引编写高效过程
BEGIN
如何有效利用索引编写高效过程    
EXEC dbo.GetOrderByID @i
如何有效利用索引编写高效过程    
SET @i=@i+1
如何有效利用索引编写高效过程
END
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
ALTER PROCEDURE dbo.GetOrderByID
如何有效利用索引编写高效过程
@i AS INT
如何有效利用索引编写高效过程
AS
如何有效利用索引编写高效过程
BEGIN
如何有效利用索引编写高效过程    
SET NOCOUNT ON;
如何有效利用索引编写高效过程    
DECLARE @sql AS NVARCHAR(52);
如何有效利用索引编写高效过程    
SET @sql = N'SELECT * FROM dbo.Orders WHERE OrderID = @ID'
如何有效利用索引编写高效过程    
EXEC sp_executesql
如何有效利用索引编写高效过程        
@stmt=@sql,
如何有效利用索引编写高效过程        
@params=N'@ID as int',
如何有效利用索引编写高效过程        
@ID=@i
如何有效利用索引编写高效过程
END
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DBCC FREEPROCCACHE;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DECLARE @i        AS INT;
如何有效利用索引编写高效过程
SET @i = 10248;
如何有效利用索引编写高效过程
WHILE @i<10252
如何有效利用索引编写高效过程
BEGIN
如何有效利用索引编写高效过程    
EXEC dbo.GetOrderByID @i
如何有效利用索引编写高效过程    
SET @i=@i+1
如何有效利用索引编写高效过程
END
如何有效利用索引编写高效过程
--动态语句的选择度测试
如何有效利用索引编写高效过程
IF OBJECT_ID(N'dbo.usp_GetOrders',N'P'IS NOT NULL
如何有效利用索引编写高效过程  
DROP PROC dbo.usp_GetOrders;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
CREATE PROC dbo.usp_GetOrders
如何有效利用索引编写高效过程  
@odate AS DATETIME
如何有效利用索引编写高效过程
AS
如何有效利用索引编写高效过程
SET NOCOUNT ON;
如何有效利用索引编写高效过程    
DECLARE @sql AS NVARCHAR(100);
如何有效利用索引编写高效过程    
SET @sql=N'SELECT OrderID, CustomerID, EmployeeID, OrderDate
如何有效利用索引编写高效过程            FROM dbo.Orders
如何有效利用索引编写高效过程            WHERE OrderDate >= @odate OPTION(RECOMPILE);
'
如何有效利用索引编写高效过程    
EXEC sp_executesql
如何有效利用索引编写高效过程        
@stmt=@sql,
如何有效利用索引编写高效过程        
@params=N'@odate as datetime',
如何有效利用索引编写高效过程        
@odate=@odate
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
SELECT OrderID, CustomerID, EmployeeID, OrderDate
如何有效利用索引编写高效过程            
FROM dbo.Orders
如何有效利用索引编写高效过程            
WHERE OrderDate >= '19980506' option(recompile)
如何有效利用索引编写高效过程
--选择度高的测试
如何有效利用索引编写高效过程
EXEC dbo.usp_GetOrders '19980506';
如何有效利用索引编写高效过程
--选择度低的测试
如何有效利用索引编写高效过程
EXEC dbo.usp_GetOrders '19960101';
如何有效利用索引编写高效过程
--查看缓存计划
如何有效利用索引编写高效过程
SELECT *
如何有效利用索引编写高效过程
FROM sys.syscacheobjects
如何有效利用索引编写高效过程
WHERE sql NOT LIKE '%cache%'
如何有效利用索引编写高效过程  
AND sql LIKE '%usp_GetOrders%';
如何有效利用索引编写高效过程
--清除缓存计划
如何有效利用索引编写高效过程
DBCC FREEPROCCACHE;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程
--动态语句EXEC
如何有效利用索引编写高效过程
IF OBJECT_ID(N'dbo.usp_GetOrders',N'P'IS NOT NULL
如何有效利用索引编写高效过程  
DROP PROC dbo.usp_GetOrders;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
CREATE PROC dbo.usp_GetOrders
如何有效利用索引编写高效过程  
@odate AS varchar(10)
如何有效利用索引编写高效过程
AS
如何有效利用索引编写高效过程
SET NOCOUNT ON;
如何有效利用索引编写高效过程    
DECLARE @sql AS VARCHAR(120);
如何有效利用索引编写高效过程    
SET @sql='SELECT OrderID, CustomerID, EmployeeID, OrderDate
如何有效利用索引编写高效过程            FROM dbo.Orders
如何有效利用索引编写高效过程            WHERE OrderDate >=
'''+@odate+''';'
如何有效利用索引编写高效过程    
print @sql
如何有效利用索引编写高效过程    
EXEC(@sql)
如何有效利用索引编写高效过程
--OPTION(RECOMPILE);
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
SELECT OrderID, CustomerID, EmployeeID, OrderDate
如何有效利用索引编写高效过程            
FROM dbo.Orders
如何有效利用索引编写高效过程            
WHERE OrderDate >='19980506'
如何有效利用索引编写高效过程
select convert(datetime,'19980506')
如何有效利用索引编写高效过程
--选择度高的测试
如何有效利用索引编写高效过程
EXEC dbo.usp_GetOrders '19980506';
如何有效利用索引编写高效过程
--选择度低的测试
如何有效利用索引编写高效过程
EXEC dbo.usp_GetOrders '19960101';
如何有效利用索引编写高效过程
--查看缓存计划
如何有效利用索引编写高效过程
SELECT *
如何有效利用索引编写高效过程
FROM sys.syscacheobjects
如何有效利用索引编写高效过程
WHERE sql NOT LIKE '%cache%'
如何有效利用索引编写高效过程  
AND sql LIKE '%usp_GetOrders%';
如何有效利用索引编写高效过程
--清除缓存计划
如何有效利用索引编写高效过程
DBCC FREEPROCCACHE;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--============================================================
如何有效利用索引编写高效过程--
日志相关
如何有效利用索引编写高效过程--
============================================================
如何有效利用索引编写高效过程
DBCC LOGINFO;
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
DBCC SQLPERF(LOGSPACE);
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--2005
如何有效利用索引编写高效过程
WHILE 1 = 1
如何有效利用索引编写高效过程
BEGIN
如何有效利用索引编写高效过程  
UPDATE TOP(5000) dbo.A
如何有效利用索引编写高效过程    
SET CustomerID = N'ABCDE'
如何有效利用索引编写高效过程  
WHERE CustomerID = N'OLDWO';
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程  
IF @@rowcount < 5000 BREAK;
如何有效利用索引编写高效过程
END
如何有效利用索引编写高效过程
GO
如何有效利用索引编写高效过程
--2000
如何有效利用索引编写高效过程
SET ROWCOUNT 5000;
如何有效利用索引编写高效过程
WHILE 1 = 1
如何有效利用索引编写高效过程
BEGIN
如何有效利用索引编写高效过程  
DELETE FROM dbo.LargeOrders
如何有效利用索引编写高效过程  
WHERE OrderDate < '19970101';
如何有效利用索引编写高效过程
如何有效利用索引编写高效过程  
IF @@rowcount < 5000 BREAK;
如何有效利用索引编写高效过程
END
如何有效利用索引编写高效过程
SET ROWCOUNT 0;
如何有效利用索引编写高效过程

相关文章: