数据库调优过程(二):找到IO不存在问题,而是sqlserver单表写入IO瓶颈
- 物理机上测试IO是否为瓶颈:
使用一个死循环insert into测试数据库最大写入速度:
use [iTest]; declare @index int; set @index=0; while @index>=0 begin set @index=@index+1; INSERT into [g].[MR] ([TimeStamp],[RTime],[STime],[ETime],[Period],[ObjID],[SID],[CID] ,[Ueid],[GId],[Code],[ScEarfcn],[ScPCI],[ScRSRP],[ScRSRQ] ,[ScRTTD],[ScPHR],[ScAOA],[ScSinrUL],[ScRIP]) VALUES (GETDATE(),GETDATE(),GETDATE(),GETDATE() ,1,11,22,33,44,44,'1222',22,33 ,44,55,66,77,88,99,00,111,null); end GO
结果发现一个问题,写入数据库iTest.mdf的速度只有几百千字节每秒,而写入iTest_log.ldf的速度也是几百字千节每秒,但是写入日志的速度要要多于数据库文件的速度,约在4倍的速度。他们两个之和才有将近1M字节每秒。
而在客户机上,我们采用生成一个文件基本速度也是5M每秒的速度,不管是大文件考别还是小文件拷贝,基本上的速度都是保持在0-70M每秒的速度,显然磁盘在上边测试磁盘的写入速度基本上没有达到饱和程度。
初步判断是sqlserver的内部控制的机制,导致单个表写入有限制,没有使得单个表的写入速度达到系统级别的极限。
- 测试:
xp_cmdshell 怎么开启
http://www.cnblogs.com/atree/p/SQL_SERVER_xp_cmdshell.html
sp_configure 'show_advanced options',1; reconfigure go sp_configure 'xp_cmdshell',1; reconfigure go
bcp 总结:http://rsljdkt.iteye.com/blog/1147707
bcp需要登录账户,数据库服务器\数据库实例信息: http://blog.sina.com.cn/s/blog_7ed5a808010140sl.html
创建格式化文件 (SQL Server):https://msdn.microsoft.com/zh-cn/library/ms191516.aspx
bcp工具使用MSDN文档:https://msdn.microsoft.com/zh-cn/library/ms162802.aspx
使用 BULK INSERT 或 OPENROWSET(BULK...) 导入大容量数据(SQL Server)MSDN文档:https://msdn.microsoft.com/zh-cn/library/ms175915.aspx
use iTest; exec master..xp_cmdshell 'BCP itest.g.mr out c:/mr.txt -c -S.\work -UN_p_r -PN2' --begin transaction x1 truncate table itest.g.mr; select top 1 * from itest.g.mr; exec master..xp_cmdshell 'bcp itest.g.mr in c:/mr.txt -c -S.\work -UN_p_r -PN2' select top 1 * from itest.g.mr; --rollback transaction x1;
单个这样的批量入库一版情况下能达到5m每秒速度,30W的记录,入库主表g.mr记录为10W,IO就这样子似乎变得很难提高。
如果是4个这样的批量入库,就可达到16m每秒的速度,确实把入库io占用速度提高了上来。
- 别人建议:
表分片特性:
1、一个逻辑表;
2、物理文件是多个文件。
比较核查的结果是,sqlserver中基本上是没有分片这一个功能,基本上使用的类似技术包含以下几个:
- a、表分区(真正意义的分区):partition,这些功能是sqlserver2005以后的版本中出现的功能,在之前的版本是没有该功能的,他的原理就是把一个逻辑上的表分为多个物理文件存储;
- b、表分区(非真正意义的分区):同一个服务器同一个数据库实例上:把一个逻辑表分为多个物理表,具体实现就是把一个逻辑表在物理上体现为多个表,之后使用union all把这些表合并在一起,作为一个视图的返回结果;
- c、表切片(分真正意义的切片技术):可以是同一个服务器也可以是不同服务器在不同的数据库实例上:把一个逻辑意义相同的表分布在不同的服务器或者同一个服务器不同的数据库实例上,之后通过sp_addlinkedserver添加远程连接数据库的表,之后把这些表使用union all连接起来,作为一个视图的返回结果。这个应用感觉怪怪的。如果分表就是数量大,当数据量大时,这个技术方案是行不通的,具体未验证过!!!可能会有一些特定的业务需要吧。
备注:
a/b方案详细讲解:http://www.cnblogs.com/zhuawang/archive/2012/07/15/2592368.html
a方案使用讲解:http://wenku.baidu.com/link?url=sEX5NRzEcvjOMYNnE7_5ro9rUwh6cKtJfNTb6iyNM4NycuOThmyOJVyZSs4JhALi2VOU-OYih7YyYYJNj7lnj48CDGNvGy40e48svSg6ao3
a方案赵洁真实使用经验及忠告:http://blog.zhaojie.me/2010/03/sharding-by-id-characteristic.html
a方案使用介绍:http://www.cnblogs.com/knowledgesea/p/3696912.html
b方案msdn讲解:(Creating Distributed Partitioned Views)https://msdn.microsoft.com/en-us/library/ms188299.aspx
-----b方案特别说明:Bulk importing into a partitioned view is not supported by the bcp command, or the BULK INSERT statement, or the INSERT ... SELECT * FROM OPENROWSET(BULK...) statement. However, you can insert multiple rows into a partitioned view by using an INSERT statement.
b方案具体使用实例1:http://blog.csdn.net/kk185800961/article/details/46482769
b方案具体使用实例2:http://www.veryhuo.com/a/view/9534.html
info中提到sqlserver会有真正的切片技术:http://www.infoq.com/cn/news/2011/02/SQL-Sharding,可是所谓的切片就是分区+索引限制吗?
实现快速复制:
可以通过数据管道和外部表也可以实现数据库间的快速复制。
sqlserver类似技术:订阅,推送,和我们要解决数据库写入瓶颈的量级级别不在一个要求水准上。
基础才是编程人员应该深入研究的问题,比如:
1)List/Set/Map内部组成原理|区别
2)mysql索引存储结构&如何调优/b-tree特点、计算复杂度及影响复杂度的因素。。。
3)JVM运行组成与原理及调优
4)Java类加载器运行原理
5)Java中GC过程原理|使用的回收算法原理
6)Redis中hash一致性实现及与hash其他区别
7)Java多线程、线程池开发、管理Lock与Synchroined区别
8)Spring IOC/AOP 原理;加载过程的。。。
【+加关注】。