SQL SERVER--指定查询优化参数

默认情况下,查询语句在第一次执行时根据查询参数进行优化并将执行计划缓存到计划高速缓存里以便后续查询可以复用。

但对于某些数据不均匀分布的情况,第一次执行时所使用的参数会导致:

1.执行计划对当前参数相对是最优的

2.执行计划对其他大部分参数是较差的

复制代码
USE [Demo1]
GO

/****** Object:  Table [dbo].[T1]    Script Date: 10/27/2012 09:57:28 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
--========================================================================
--创建表
CREATE TABLE [dbo].[T1](
    [RowId] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [ObjectID] [int] NOT NULL,
    [ObjectName] [sysname] NOT NULL,
    [RowStatus] [int] NOT NULL,
) ON [PRIMARY]
GO
--========================================================================
--创建索引
CREATE NONCLUSTERED INDEX [NI_T1_RowStatus] ON [dbo].[T1] 
(
    [RowStatus] ASC
)
GO
--========================================================================
--创建存储过程
CREATE PROCEDURE dbo.DemoTest
    -- Add the parameters for the stored procedure here
    @RowStatus int
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    SELECT * from dbo.T1
    WHERE T1.RowStatus=@RowStatus
    --OPTION(OPTIMIZE FOR(@RowStatus=1))
    
END
GO
--========================================================================
--插入2w+[RowStatus]=1的数据和一条[RowStatus]=2的数据
--使得[RowStatus]数据严重分布不均匀
INSERT INTO [dbo].[T1]
           ([ObjectID]
           ,[ObjectName]
           ,[RowStatus])
     VALUES
           (1,'o1',2)
GO
INSERT INTO [dbo].[T1]
           ([ObjectID]
           ,[ObjectName]
           ,[RowStatus])
SELECT A.object_Id AS ObjectID,
A.Name AS ObjectName ,
1 AS RowStatus 
FROM sys.columns A CROSS JOIN sys.columns  B
--========================================================================
GO
EXEC dbo.DemoTest @RowStatus=2
GO
EXEC dbo.DemoTest @RowStatus=1
GO
--由于[RowStatus]=1的数据在所有数据的99.99%,
--因此EXEC dbo.DemoTest @RowStatus=1查询时做全表扫描会是最优的选择,
--而对EXEC dbo.DemoTest @RowStatus=2查询时做索引查找会是最优的选择
--如果只有少数几次执行@RowStatus=2和多次执行@RowStatus=1的话,
--而我们不能保证每次数据库重启后第一次执行EXEC dbo.DemoTest @RowStatus=1来缓冲该计划,
--因此我们需要使用OPTION(OPTIMIZE FOR(@RowStatus=1))来为查询优化器指明参数
复制代码
--减少读锁对并发造成的影响
--使用NOLOCK 查询
SELECT * FROM dbo.T1 WITH(NOLOCK)
--修改隔离级别
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM dbo.T1
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

 

 

posted on   笑东风  阅读(373)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现

导航

点击右上角即可分享
微信分享提示