zoukankan      html  css  js  c++  java
  • SQL 2014新功能介绍系列1

    SQL Server 2014引入了内存优化的数据库技术来优化OLTP的工作性能。更特别的是,它引入了内存优化的表来提高效率以及非争夺式数据访问,还引入了本地编译的存储过程来实现业务逻辑的有效执行。

    内存中OLTP是一种为内存优化及OLTP性能优化设计的新的数据库引擎。内存中OLTP是完整集成在SQL Server中的,并不是一个分离的系统。用户可以通过定义一个被频繁访问的内存优化的表来利用内存中OLTP的优势。内存中OLTP是完全事务性的,持久性的,并且跟之前的SQLServer中的表一样可以通过T-SQL访问。一个查询语句既可以引用内存中OLTP的表也可以引用普通的表,一个事务同样也可以更新这两种表中的数据。只引用内存中 OLTP表的代价高的T-SQL存储过程可以通过本地编译的方式以备未来的性能优化。这种引擎是为了处理高并发的OLTP型的向外扩展的中间层事务而设计的。为了达到这个目的,它使用了不加锁的数据结构并且使用了一种新的多版本的积极并发控制技术。最终的结果是有选择性的迁移和增量迁移到内存中OLTP可以提供可预测的亚毫秒级的低延时和可线性扩展的高吞吐量的数据库事务。实际的性能提升会受到许多因素的影响,但是我们一般可以看到用户的工作负载有5X-20X的变化。

    本文将简单介绍内存中OLTP的新语法,并且将向您展示如何使用T-SQL和 SQL Server Management Studio (SSMS)来探索内存中OLTP.

    开始之前,我们新建一个样本数据库,如果您已经有其他数据库可以选择跳过此步骤。

    -- Optional: create database 

    CREATE DATABASE imoltp 

    GO

    SSMS: 新建一个数据库

    1.  在Object Explorer里,连接到数据库引擎的一个实例,然后展开这个实例

    2.  右击数据库,点击new database 然后输入数据库的名字

    第一步:设置您的数据库以支持内存中OLTP

    我们将要为memory_optimized_data添加一个文件组,并且添加一个该文件组的容器。这个文件组可以保证常驻内存数据的持久性,即使数据库发生崩溃或者重启。在服务器启动后的崩溃复原阶段,数据将会从该文件组复原并且重新加载回内存里。

    在创建memory_optimized_data的容器时,必须指定存储位置。在本例中我们选择文件夹‘c:data’。请确保选择的文件夹在执行脚本之前是存在的。

    -- enable for in-memory OLTP - change file path as needed 

    ALTER DATABASE imoltp ADD FILEGROUP imoltp_mod CONTAINS MEMORY_OPTIMIZED_DATA 

    ALTER DATABASE imoltp ADD FILE (name='imoltp_mod1', filename='c:dataimoltp_mod1') TO FILEGROUP imoltp_mod 

    GO

    SSMS: 添加memory_optimized_data文件组和它的容器,

    1.   在Object Explorer中, 展开数据库节点, 右键点击数据库,单击属性

    2.  添加一个新的内存优化数据的文件组,点击文件组页面。在MEMORY OPTIMIZED DATA选项下,单击添加文件组并设置文件组的各项值。

    3.  在文件组中添加文件,点击general 页面。 在Database files下,点击添加并且输入文件的各项值。File type 设置为FILESTREAM Data。

    第二步:创建您的第一个内存优化的表

    我们现在已经准备好创建第一个内存优化的表。目前我们有两张表,‘ShoppingCart’和‘UserSession’。‘ShoppingCart’是一个持久化的表(默认值),这意味着表中的内容是存储在磁盘上的,不会因为服务器崩溃而丢失。‘UserSession’是一个非持久化的表(DURABILITY=SCHEMA_ONLY),这意味着表中内容仅存储在内存中,服务器重启即会丢失。

    注:SQL 2014 内存优化的表支持非聚集哈希索引(hash index)和非聚集索引(rang index)。hash索引的Bucket_cout建议值是表中能找到的唯一索引键值个数的4到8倍。

    ------------------------------------------------------------------------------------------------------------------------------------------------

    --以下表跟该篇文章没有关系,仅仅是说明如何在内存表上面加索引:

    CREATE TABLE [dbo].[Bobcat_AccessLog](
     id uniqueidentifier not null default NEWSEQUENTIALID(),
     [SN] [varchar](50) NOT NULL,
     [StationID] [varchar](60) NOT NULL,
     [LogTime] [datetime] NOT NULL,
     
     CONSTRAINT PK_Bobcat_AccessLog_ID PRIMARY KEY NONCLUSTERED HASH
     (
      ID
     )WITH (BUCKET_COUNT = 100) ,
     INDEX [IX_AccessLog_LTime]  NONCLUSTERED ([LogTime]),
     INDEX [IX_AccessLog_SN]  NONCLUSTERED ([SN],[StationID])
    ) WITH ( MEMORY_OPTIMIZED = ON , DURABILITY = SCHEMA_only )

    ------------------------------------------------------------------------------------------------------------------------------------------------

    -- create memory optimized tables 

    USE imoltp 

    GO

    -- durable table (持久化的表)

    CREATE TABLE dbo.ShoppingCart ( 

       ShoppingCartId int not null primary key nonclustered hash with    (bucket_count=2000000), 

       UserId int not null index ix_UserId nonclustered hash with (bucket_count=1000000), 

       CreatedDate datetime2 not null, 

       TotalPrice money 

    WITH (MEMORY_OPTIMIZED=ON) 

    GO

    -- non-durable table (非持久化的表)

    CREATE TABLE dbo.UserSession ( 

       SessionId int not null primary key nonclustered hash with (bucket_count=400000), 

       UserId int not null, 

       CreatedDate datetime2 not null, 

       ShoppingCartId int, 

       index ix_UserId nonclustered hash (UserId) with (bucket_count=400000) 

    WITH(MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_ONLY) 

    GO

    SSMS:新建一个内存优化表

    1.    在Object Explorer,右键单击您数据库的Tables节点,点击new,然后点击Memory Optimized Table。然后可以看到创建内存优化表的模板。

    2.    替换模板中的参数,在query菜单中点击Specify Values for Template Parameters。快捷键是Ctrl-Shift-M。

    第三步:加载您的数据

    您可以通过多种方式把数据加载到表中,包括 INSERT .. SELECT from一个已经存在的存储在磁盘上的表和BCP。在本例中我们使用简单的INSERT语句来加载数据。

    -- Basic DML 

    -- insert a few rows 

    INSERT dbo.UserSession VALUES (1,342,GETUTCDATE(),4) 

    INSERT dbo.UserSession VALUES (2,65,GETUTCDATE(),NULL) 

    INSERT dbo.UserSession VALUES (3,8798,GETUTCDATE(),1) 

    INSERT dbo.UserSession VALUES (4,80,GETUTCDATE(),NULL) 

    INSERT dbo.UserSession VALUES (5,4321,GETUTCDATE(),NULL) 

    INSERT dbo.UserSession VALUES (6,8578,GETUTCDATE(),NULL) 

    INSERT dbo.ShoppingCart VALUES (1,8798,GETUTCDATE(),NULL) 

    INSERT dbo.ShoppingCart VALUES (2,23,GETUTCDATE(),45.4) 

    INSERT dbo.ShoppingCart VALUES (3,80,GETUTCDATE(),NULL) 

    INSERT dbo.ShoppingCart VALUES (4,342,GETUTCDATE(),65.4) 

    GO

    -- verify table contents 

    SELECT * FROM dbo.UserSession 

    SELECT * FROM dbo.ShoppingCart 

    GO

    SSMS:查看内存优化的表中的内容

    ⦁   在Object Explorer中,右键单击你的内存优化的表, 点击Script Table as,点击SELECT To,点击New Query Editor Window然后执行显示出来的query。

    第四步:更新统计信息

    内存优化的表不支持auto_update_statistics,因此统计信息需要手动进行更新。您可以使用UPDATE STATISTICS来更新单个表的统计信息或者sp_updatestats来更新数据库中的所有表的统计信息。

    -- update statistics on memory optimized tables 

    UPDATE STATISTICS dbo.UserSession WITH FULLSCAN, NORECOMPUTE 

    UPDATE STATISTICS dbo.ShoppingCart WITH FULLSCAN, NORECOMPUTE 

    GO

    第五步:执行查询

    现在您已经做好了执行查询的准备。因为查询需要访问内存优化的表,他们将会受益于不加锁的数据结构,从而提高了数据访问的效率。以下是一些例子:

    -- in an explicit transaction, assign a cart to a session and update the total price. 

    -- note that the isolation level hint is required for memory-optimized tables with 

    -- SELECT/UPDATE/DELETEstatements in explicit transactions 

    BEGIN TRAN 

      UPDATE dbo.UserSession WITH (SNAPSHOT) SET ShoppingCartId=3 WHERE SessionId=4 

      UPDATE dbo.ShoppingCart WITH (SNAPSHOT) SET TotalPrice=65.84 WHERE ShoppingCartId=3 

    COMMIT 

    GO 

    -- verify table contents 

    SELECT *  FROM dbo.UserSession u JOIN dbo.ShoppingCart s on u.ShoppingCartId=s.ShoppingCartId 

    WHERE u.SessionId=4 

    GO

    第六步:创建本地编译的存储过程

    为了进一步优化内存优化表的访问以及优化您的业务逻辑的执行,您可以选择创建本地编译的存储过程。这些存储过程是使用Transact-SQL创建的,但并不支持完整的Transaction-SQL环境。具体细节可参考联机丛书。

    以下是一个访问之前我们创建的表的本地编译的存储过程的例子。

    -- natively compiled stored procedure for assigning a shopping cart to a session 

    CREATE PROCEDURE dbo.usp_AssignCart @SessionId int 

    WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER 

    AS 

    BEGIN ATOMIC 

    WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english')

      DECLARE @UserId int, 

       @ShoppingCartId int

      SELECT @UserId=UserId, @ShoppingCartId=ShoppingCartId 

      FROM dbo.UserSession WHERE SessionId=@SessionId

      IF @UserId IS NULL 

       THROW 51000, 'The session or shopping cart does not exist.', 1

       UPDATE dbo.UserSession SET ShoppingCartId=@ShoppingCartId WHERE SessionId=@SessionId 

    END 

    GO

    EXEC usp_AssignCart 1 

    GO

    下面的存储过程通过向内存优化表中插入大量数据行来测试本地编译的存储过程的性能。该脚本插入了1,000,000行数据。

    需要注意的是如果写事物日志文件变成应用的性能瓶颈,SQL Server允许您采用非持久化的表(DURABILITY=SCHEMA_ONLY)来完全除去写事物日志。.

    -- natively compiled stored procedure for inserting a large number of rows 

    --   this demonstrates the performance of native procs 

    CREATE PROCEDURE dbo.usp_InsertSampleCarts @StartId int, @InsertCount int 

    WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER 

    AS 

    BEGIN ATOMIC 

    WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english')

      DECLARE @ShoppingCartId int = @StartId

      WHILE @ShoppingCartId < @StartId + @InsertCount 

      BEGIN 

       INSERT INTO dbo.ShoppingCart VALUES 

            (@ShoppingCartId, 1, '2013-01-01T00:00:00', NULL) 

       SET @ShoppingCartId += 1 

      END

    END 

    GO

    -- insert 1,000,000 rows 

    DECLARE @StartId int = (SELECT MAX(ShoppingCartId)+1 FROM dbo.ShoppingCart) 

    EXEC usp_InsertSampleCarts @StartId, 1000000 

    GO

    -- verify the rows have been inserted 

    SELECT COUNT(*) FROM dbo.ShoppingCart 

    GO

    SSMS:创建本地编译的存储过程

    1.   在 Object Explorer中,右键单击您的数据库中的Stored Procedures 节点,点击New,然后点击 Natively Compiled Stored Procedure。创建本地编译的存储过程的模板将会显示在界面上。

    2.   替换模板中的参数,点击Query 菜单下的 Specify Values for Template Parameters。快捷键是Ctrl-Shift-M.

    更多关于内存中OLTP概念的细节和语法, 请参看联机丛书 。这就是今天的分享,更多SQL 2014新功能介绍请持续关注本博客。我们会在接下来的每周对此系列做更新。

  • 相关阅读:
    jenkins 参数化构建,获取git分支
    maven 历史版本下载
    spring mybatis 多个数据源配置
    springmvc 加载静态文件失败
    java服务覆盖率统计 jacoco ant
    testng监听ISuiteListener
    记录一下这几天遇到的坑(.netcore 代理问题)
    Js获取客户端用户Ip地址
    如何获取AWS的Access Key ID 和 Secret Access Key (Unable to find credentials)
    记录一个EF连接查询的异常:the entity or complex type 'x' cannot be constructed in a linq to entities query
  • 原文地址:https://www.cnblogs.com/ziqiumeng/p/7722172.html
Copyright © 2011-2022 走看看