数据库调优过程(四):提高数据库写入修改方案

目前先后做了以下调整:

1、单表多个线程写入的时候,总会因为写入log或单文件写入速度的限制,导致IO提到不了成为入库的瓶颈;为了提到入库IO速度,我们采取分表策略,一次性拆分到一个ENB为单元的物理表;

2、修改批量入库方案:从监控IO来看,IO的写入速度确实有提高,但是同时写入多个表过程是单线程批量写入单个表,后来修改为并行写入多个表。但是依然存在内存居高不下的情况,这样的一个enb往往会造成内存居高不下,以至于内存资源成为瓶颈;

3、为了解决内存成为瓶颈,在内存处理时,每当表记录到达50w,就批量入库一次,以便用来清理内存信息;

4、基于以上方案,如果集中遇到大文件时,依然会出现内存不足,一个enb读取解析,入库都占用时长过长,而有小文件时,就不会出现占用时间过长的问题,所以针对任务采取控制同时运行的任务大文件不超过两个;

5、之前一次读取enb的下的所有文件,拆分为一次性只读取一个文件,就解析入库,缩短每个线程占用时长,避免因为单个线程占用时长过长进而对cpu调度造成压力,避免线程给后置的情况发生;而且改为小文件为一个单独线程来处理后,每个线程占用的内存会降低,会增加同时入库同一个物理表的线程数增加,进而有可能提到IO利用率,进而提高入库性能。

拆分为一个文件已入库,就会涉及到并行入库同一个或多个物理表的情况,而此时表结构是主子表结构,主表与字表之间通过一个oid来关联,必须要维护这个oid,以保证主表与字表之间的关联关系,如果并行插入单个表就常常会出现同一个oid已被占用的异常情况,我们采用一个GlobalMaxOID,来占坑每个物理表已经被占用的OID。

在处理OID占坑策略时遇到了一下问题:

并行处理一个ENB内部文件\\17x.xx.x.xx\xx\FTP2\xx\20160513\xx\Txxx.xml.gz时抛出异常
事务(进程 ID 69)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。

后来发现从数据方面来解决希望不大,从程序的角度做了一下调整:

 1 /****** Object:  StoredProcedure [dbo].[GetGlobalMaxOID]    Script Date: 07/13/2016 23:50:04 ******/
 2 DROP PROCEDURE [dbo].[GetGlobalMaxOID]
 3 GO
 4 /****** Object:  Table [dbo].[GlobalMaxOID]    Script Date: 07/13/2016 23:50:03 ******/
 5 DROP TABLE [dbo].[GlobalMaxOID]
 6 GO
 7 /****** Object:  Table [dbo].[GlobalMaxOID]    Script Date: 07/13/2016 23:50:03 ******/
 8 SET ANSI_NULLS ON
 9 GO
10 SET QUOTED_IDENTIFIER ON
11 GO
12 CREATE TABLE [dbo].[GlobalMaxOID](
13     [ENodeBID] [int] NOT NULL,
14     [TableName] [nvarchar](64) NOT NULL,
15     [MaxOID] [bigint] NOT NULL,
16     [Flag] [int] NOT NULL
17 ) ON [PRIMARY]
18 GO
19 /****** Object:  StoredProcedure [dbo].[GetGlobalMaxOID]    Script Date: 07/13/2016 23:50:04 ******/
20 SET ANSI_NULLS ON
21 GO
22 SET QUOTED_IDENTIFIER ON
23 GO
24 -- =============================================
25 -- Author:        tommy duan
26 -- Create date: 2016-07-12
27 -- Description: OID 占坑
28 -- =============================================
29 CREATE PROCEDURE [dbo].[GetGlobalMaxOID]
30     @ENodeBID int,
31     @TableName nvarchar(64),
32     @TempCount int
33 AS
34 BEGIN
35     SET NOCOUNT ON;
36
37     Declare @MaxOID bigint;
38
39     Set XACT_ABORT ON;
40     Begin Transaction
41         if not exists(Select ENodeBID From dbo.GlobalMaxOID Where ENodeBID=@ENodeBID and TableName=@TableName) begin
42             insert into dbo.GlobalMaxOID(ENodeBID,TableName,MaxOID,Flag)VALUES(@ENodeBID,@TableName,0,0);
43         end
44
45         Update dbo.GlobalMaxOID Set Flag=1 Where ENodeBID=@ENodeBID and TableName=@TableName;
46
47         Select @MaxOID=MaxOID From dbo.GlobalMaxOID Where ENodeBID=@ENodeBID and TableName=@TableName;
48
49         Update dbo.GlobalMaxOID Set MaxOID=(@MaxOID+@TempCount),Flag=0 Where ENodeBID=@ENodeBID and TableName=@TableName;
50     Commit Transaction;
51
52     Select @MaxOID;
53 END
54 GO

使用lock:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Data.SqlClient;
 6 using System.Threading.Tasks;
 7 using System.Configuration;
 8
 9 namespace TestGlobalMaxOID
10 {
11     class Task
12     {
13         public int ENodeBID { get; set; }
14         public int TempCount { get; set; }
15         public string ConnectionString { get; set; }
16     }
17
18     class Program
19     {
20         static object locker = new object();
21
22         static void Main(string[] args)
23         {
24             string tableName = string.Empty;
25
26             Parallel.For(10000, 10100, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (int enodebid) =>
27             {
28                 List<Task> tasks = new List<Task>();
29                 for (int i = 0; i < 100; i++)
30                 {
31                     tasks.Add(new Task() { ENodeBID = enodebid, TempCount = 1000000, ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString });
32                 }
33
34                 Parallel.ForEach(tasks, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (Task task) =>
35                 {
36                     Console.WriteLine(GetMaxOIDByTableNameAndENodeBID(task.ConnectionString, "MRO", task.ENodeBID, task.TempCount));
37                 });
38             });
39
40
41             Console.WriteLine("Complete!");
42             Console.ReadKey();
43
44         }
45
46         static long GetMaxOIDByTableNameAndENodeBID(string connectionString, string tableName, int eNodeBId, int tempCount)
47         {
48             lock (locker)
49             {
50                 using (SqlConnection connection = new SqlConnection(connectionString))
51                 {
52                     using (SqlCommand command = new SqlCommand())
53                     {
54                         connection.Open();
55
56                         command.Connection = connection;
57                         command.CommandText = "[dbo].[GetGlobalMaxOID]";
58                         command.CommandType = System.Data.CommandType.StoredProcedure;
59
60                         command.Parameters.Add(new SqlParameter("@ENodeBID", eNodeBId));
61                         command.Parameters.Add(new SqlParameter("@TableName", tableName));
62                         command.Parameters.Add(new SqlParameter("@TempCount", tempCount));
63
64                         object obj = command.ExecuteScalar();
65
66                         return Convert.ToInt64(obj);
67                     }
68                 }
69             }
70         }
71
72     }
73 }
时间: 2024-12-19 17:35:19

数据库调优过程(四):提高数据库写入修改方案的相关文章

记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?)

记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?) 前几天帮客户优化一个数据库,那个数据库的大小是6G 这麽小的数据库按道理不会有太大的性能问题的,但是客户反应说CPU占用很高,经常达到80%~90% 我检查了任务管理器,确实是SQLSERVER占的CPU 而服务器的内存是16G内存,只占用了7G+ 客户的环境: Windows2008R2 SQLSERVER2005 SP3 64位 企业版 服务器内存:16G CPU:8核 RDS:阿里云主机

数据库调优过程(三):提高数据库写入性能方案调查

客户给出建议方案: 一直听客户这边说mycat这个东东,一头雾水,这是什么东东,只听说过mysql不知道mycat,瞬间被鄙视N次方次. 客户提到数据库分片.表复制能提高数据库性能,但可惜对这些技术好像不知道,只知道表分区,不知道分片,知道表批量复制,可以被订阅推送等,及主从复制,不知道这里说的表复制到时所谓什么技术. 客户提到MongoDB,PostgreSQL比较强悍,基本上可以实现集群型结构,表分片相关复制相关技术,但到底在实际应用中怎么是个怎么运行的. 带着上边的问题,我认真的查阅了网上

MySQL数据库调优经验

?RDS for MySQL 由亚洲唯一WebScaleSQL团队维护内核源码,结合阿里巴巴多年MySQL数据库调优经验,从数据库源码层及数据库参数进行了性能优化,在相近规格配置下,RDS for MySQL性能值能达到自建数据库性能的3倍以上. RDS for MySQL针对通用的场景,在内核做了一系列的优化: 1. 改进了InnoDB redo组提交功能,多线程并发写入的情况下能有10%以上的速度提升. 2. 优化锁,对一些会引起串行化的大锁进行了拆分,能够有效避免长时间的读锁等待,提升数据

数据库调优的方法有那些

1.引言        数据库调优可以使数据库应用运行得更快,它需要综合考虑各种复杂的因素.将数据均 匀分布在磁盘上可以提高I/O 利用率,提高数据的读写性能:适当程度的非规范化可以改善 系统查询性能:建立索引和编写高效的SQL 语句能有效避免低性能操作:通过锁的调优解 决并发控制方面的性能问题.     数据库调优技术可以在不同的数据库系统中使用,它不必纠缠于复杂的公式和规则,然 而它需要对程序的应用.数据库管理系统.查询处理.并发控制.操作系统以及硬件有广泛 而深刻的理解. 2.计算机硬件调

(转)从“如何设计用户超过1亿的应用”说起—数据库调优实战

摘要:如果企业计划构建高性能的SaaS应用,仅凭云服务基础设施是不够的.如何基于云服务平台设计并实施符合自身业务特点的系统架构,是决定产品性能的关键.本文将讲述我们如何利用云服务,解决海量用户的数据库使用问题. 杭州湖畔网络技术有限公司是一家专业提供SaaS化电商ERP服务的创业公司,主要用户群体为经营淘宝.天猫.京东等主流电商平台.自建商城.线下渠道的商家及中小企业.作为SaaS服务提供商,服务数万乃至数十万级用户是业务架构初期就必须考虑的问题.庞大的用户群以及海量的用户数据意味着基础设施的构

MySQL面试必考知识点:揭秘亿级高并发数据库调优与最佳实践法则

做业务,要懂基本的SQL语句: 做性能优化,要懂索引,懂引擎: 做分库分表,要懂主从,懂读写分离... 数据库的使用,是开发人员的基本功,对它掌握越清晰越深入,你能做的事情就越多. 今天我们用10分钟,重点梳理一遍以下几方面: 数据库知识点汇总: 数据库事务特性和隔离级别: 详解关系型数据库.索引与锁机制: 数据库调优与最佳实践: 面试考察点及加分项. 知识点汇总 一.数据库的不同类型 1.常用的关系型数据库 Oracle:功能强大,主要缺点就是贵 MySQL:互联网行业中最流行的数据库,这不仅

[转]10分钟梳理MySQL知识点:揭秘亿级高并发数据库调优与最佳实践法则

转:https://mp.weixin.qq.com/s/RYIiHAHHStIMftQT6lQSgA 做业务,要懂基本的SQL语句: 做性能优化,要懂索引,懂引擎: 做分库分表,要懂主从,懂读写分离... 数据库的使用,是开发人员的基本功,对它掌握越清晰越深入,你能做的事情就越多. 今天我们用10分钟,重点梳理一遍以下几方面: 数据库知识点汇总: 数据库事务特性和隔离级别: 详解关系型数据库.索引与锁机制: 数据库调优与最佳实践: 面试考察点及加分项. 一.数据库的不同类型 1.常用的关系型数

数据库调优分层思想

数据库调优分层思想 1.调优策略 1)*号的处理(只提取必要字段,减少流量) 最好是用,有用的字段,减少流量. 表结构会改变,增加或者减少某列,如果*号全部查询出来 会造成代码逻辑错误. 2)大SQL(拆分,逐步缩小结果集) 大SQL执行起来非常耗时, where 后面带子句,或者读表联合查询. 或者临时表 暂时存储结果集 3)合理的索引(where子句后面的条件) 4)类型转换(‘’符号的使用) 在进行查询操作的时候把  ‘’带上 5)尽量不要用范围查询,或者缩小检索范围(程序逻辑update

调优过程

性能调优 1 百胜表规范 USE ERP_DW GO /* 功能说明: 创建[区域]维度表 修改说明: Create by LY on 2011-09-07 */ IF EXISTS (SELECT 1 FROM SYSOBJECTS WHERE id = OBJECT_ID('Dim_Area') AND type = 'U') BEGIN DROP TABLE Dim_Area END GO CREATE TABLE [dbo].[Dim_Area] ( AreaCode VARCHAR(2