加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

sql-server – SQL Server中的大量数据和机能

发布时间:2021-05-17 08:27:30 所属栏目:编程 来源:网络整理
导读:我编写了一个带有SQL Server后端的应用措施,用于网络和存储大量的记录.我已经计较出,在最岑岭时,均匀记录量约莫在天天30-40亿(运营20小时)的大道上. 我的原始办理方案(在我完成数据的现实计较之前)是让我的应用措施将记录插入到我的客户查询的统一个表中.显然
副问题[/!--empirenews.page--]

我编写了一个带有SQL Server后端的应用措施,用于网络和存储大量的记录.我已经计较出,在最岑岭时,均匀记录量约莫在天天30-40亿(运营20小时)的大道上.

我的原始办理方案(在我完成数据的现实计较之前)是让我的应用措施将记录插入到我的客户查询的统一个表中.显然,这很快就会瓦解和销毁,由于查询插入了大量记录的表是不行能的.

我的第二个办理方案是行使2个数据库,一个用于应用措施吸取的数据,另一个用于客户端停当数据.

我的应用措施将吸取数据,将其分成约莫100k笔记录并批量插入到姑且表中.在约莫100k记录之后,应用措施将动态建设另一个具有与早年沟通的模式的姑且表,并开始插入该表.它将在功课表中建设一个记录,个中包括具有100k记录的表的名称,而且SQL Server端的存储进程会将数据从登台表移动到客户端停当出产表,然后删除我的应用措施建设的表姑且表.

除具有jobs表的登台数据库外,两个数据库都具有沟通模式的5个表的沟通荟萃.登台数据库在大量记录地址的表上没有完备性束缚,密钥,索引等.如下所示,表名是SignalValues_staging.方针是让我的应用措施尽快将数据打入SQL Server.即时建设表以便可以轻松迁徙的事变流程很是有用.

以下是我的姑且数据库中的5个相干表,以及我的jobs表:


我编写的存储进程处理赏罚从全部登台表中移动数据并将其插入出产中.下面是我的存储进程中从登台表插入到出产中的部门:

-- Signalvalues jobs table.
SELECT *,ROW_NUMBER() OVER (ORDER BY JobId) AS 'RowIndex'
INTO #JobsToProcess
FROM 
(
    SELECT JobId,ProcessingComplete,SignalValueStagingTableName AS 'TableName',(DATEDIFF(SECOND,(SELECT last_user_update
                              FROM sys.dm_db_index_usage_stats
                              WHERE database_id = DB_ID(DB_NAME())
                                AND OBJECT_ID = OBJECT_ID(SignalValueStagingTableName)),GETUTCDATE())) SecondsSinceLastUpdate
    FROM SignalValueJobs
) cte
WHERE cte.ProcessingComplete = 1
   OR cte.SecondsSinceLastUpdate >= 120

DECLARE @i INT = (SELECT COUNT(*) FROM #JobsToProcess)

DECLARE @jobParam UNIQUEIDENTIFIER
DECLARE @currentTable NVARCHAR(128) 
DECLARE @processingParam BIT
DECLARE @sqlStatement NVARCHAR(2048)
DECLARE @paramDefinitions NVARCHAR(500) = N'@currentJob UNIQUEIDENTIFIER,@processingComplete BIT'
DECLARE @qualifiedTableName NVARCHAR(128)

WHILE @i > 0
BEGIN

    SELECT @jobParam = JobId,@currentTable = TableName,@processingParam = ProcessingComplete
    FROM #JobsToProcess 
    WHERE RowIndex = @i 

    SET @qualifiedTableName = '[Database_Staging].[dbo].['+@currentTable+']'

    SET @sqlStatement = N'

        --Signal values staging table.
        SELECT svs.* INTO #sValues
        FROM '+ @qualifiedTableName +' svs
        INNER JOIN SignalMetaData smd
            ON smd.SignalId = svs.SignalId  


        INSERT INTO SignalValues SELECT * FROM #sValues

        SELECT DISTINCT SignalId INTO #uniqueIdentifiers FROM #sValues

        DELETE c FROM '+ @qualifiedTableName +' c INNER JOIN #uniqueIdentifiers u ON c.SignalId = u.SignalId

        DROP TABLE #sValues
        DROP TABLE #uniqueIdentifiers

        IF NOT EXISTS (SELECT TOP 1 1 FROM '+ @qualifiedTableName +') --table is empty
        BEGIN
            -- processing is completed so drop the table and remvoe the entry
            IF @processingComplete = 1 
            BEGIN 
                DELETE FROM SignalValueJobs WHERE JobId = @currentJob

                IF '''+@currentTable+''' <> ''SignalValues_staging''
                BEGIN
                    DROP TABLE '+ @qualifiedTableName +'
                END
            END
        END 
    '

    EXEC sp_executesql @sqlStatement,@paramDefinitions,@currentJob = @jobParam,@processingComplete = @processingParam;

    SET @i = @i - 1
END

DROP TABLE #JobsToProcess

我行使sp_executesql,由于登台表的表名是来自jobs表中记录的文本.

这个存储进程行使我从this dba.stackexchange.com post学到的能力每2秒运行一次.

我不能办理的题目是执行插入出产的速率.我的应用措施建设姑且登台表,并以极快的速率添补记录.插入到出产中无法跟上表的数目,而且最终会稀有千个表中的多余表.我可以或许跟上传入数据的独一要领是删除出产SignalValues表上的全部键,索引,束缚等.我接下来面对的题目是该表最终会有云云多的记录,因此无法查询.

我已经实行行使[Timestamp]作为分区列来分区表无济于事.任何情势的索引城市减慢插入速率,使得它们无法跟上.其它,我必要提前几年建设数千个分区(每分钟一小时?).我无法弄清晰如安在航行中建设它们

我实行通过向名为TimestampMinute的表添加计较列来建设分区,其值为INSERT,DATEPART(MINUTE,GETUTCDATE()).照旧太慢了.

我已经实行凭证this Microsoft article将它酿成一个内存优化表.大概我不大白该怎么做,可是MOT使插入速率变慢了.

我搜查了存储进程的执行打算,发明(我以为?)最麋集的操纵是

SELECT svs.* INTO #sValues
FROM '+ @qualifiedTableName +' svs
INNER JOIN SignalMetaData smd
    ON smd.SignalId = svs.SignalId

对我来嗣魅这没故意义:我已经在存储进程中添加了挂钟记录,不然证明白这一点.

在时刻记录方面,上述特定语句在100k记录上执行约300ms.

该声明

INSERT INTO SignalValues SELECT * FROM #sValues

在100k记录上执行2500-3000ms.从表中删除受影响的记录,切合:

DELETE c FROM '+ @qualifiedTableName +' c INNER JOIN #uniqueIdentifiers u ON c.SignalId = u.SignalId

再花300ms.

我奈何才气让它更快? SQL Server可否天天处理赏罚数十亿笔记录?

假如相干,则为SQL Server 2014 Enterprise x64.

硬件设置:

我忘了在这个题目的第一遍中包括硬件.我的错.

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读