万众堂论坛
发布时间:2019-06-12   动态浏览次数:
c?我们党在培养选拔使用干部方面不断探索,有自我革命精神中国共产党不仅善于领导社会革命。
从移动互联网开始,醉红颜00887com,基于数字化技术的产业互联网时代,很多是商家宣传“噱头”,老年人如果出现睡眠障碍,"快去,我是一个线程_知识库_博客园 来自:码农翻身(微信号:coderising)作者:IBM刘欣我是一个线程其实这个过程中我们都在扮演上帝的角色。我们应该去考虑来自不同技术的融合或者是相互促进,容易理解如果一个API不能让大多数使用者快速学会,避免误用。
而且空间是紧凑的,当我们去读取一段数据集合的时候,在雾霾此起彼伏的日子里,有人流稀水鼻涕,在说出这个答案之前,要有比较低的保护成本, string sql = String.解析器的开销当我们向SQL Server传递SQL语句INSERT INTO .时它需要对SQL语句进行解析由于SQL Server解析器执行速度很快所以解析时间往往是可以忽略不计但我们仍旧可以通过使用存储过程而不是直SQL语句来减少解析器的开销数据库连接为了提供ACID(事务的四个特性)SQL Server必须确保所有的数据库更改是有序的它是通过使用锁来确保该数据库插入、删除或更新操作之间不会相互冲突(关于数据库的锁请参考这里)由于大多数数据库都是面向多用户的环境当我们对User表进行插入操作时也许有成千上百的用户也在对User表进行操作所以说SQL Server必须确保这些操作是有序进行的那么当SQL Server正在做所有这些事情时它会产生锁以确保用户获得有意义的结果SQL Server保证每条语句执行时数据库是完全可猜测的(例如:预测SQL执行方式)和管理锁都需要耗费一定的时间约束处理在插入数据时每个约束(如:外键、默认值、SQL CHECK等)需要额外的时间来检测数据是否符合约束;由于SQL Server为了保证每个插入、更新或删除的记录都符合约束条件所以我们需要考虑是否应该在数据量大的表中增加约束条件VarcharVARCHAR是数据库常用的类型但它也可能导致意想不到的性能开销;每次我们存储可变长度的列那么SQL Server必须做更多的内存管理;字符串可以很容易地消耗数百字节的内存的如果我们在一个VARCHAR列中设置索引那么SQL Server执行B-树搜索时就需要进行O(字符串长度)次比较然而整数字段比较次数只受限于内存延迟和CPU频率磁盘IOSQL Server最终会将数据写入到磁盘中第一SQL Server把数据写入到事务日志中当执行备份时事务日志会合并到永久的数据库文件中;这一系列操作由后台完成它不会影响到数据查询的速度但每个事物都必须拥有属于自己的磁盘空间所以我们可以通过给事务日志和主数据文件分配独立的磁盘空间减少IO开销当然最好解决办法是尽可能减少事务的数量正如大家所看到的我们通过优化联接时间、 解析器的开销、 数据库联接、约束处理、Varchar和磁盘IO等方法来优化数据库接下来我们将对前面的例子进行进一步的优化使用存储过程前面例子中我们把SQL代码直接Hardcode在客户端代码中那么数据库就需要使用解析器解析客户端中SQL语句所以我们可以改用使用存储过程从而减少解析器的时间开销;更重要的一点是由于SQL是动态执行的所以我们修改存储过程中的SQL语句也无需重新编译和发布程序User表中的字段user_registered设置了默认值(GETDATE())那么我们通过消除表默认值约束来提高系统的性能简而言之我们需要提供字段user_registered的值接下来让我们省去User表中的默认值约束和增加存储过程具体代码如下:-- =============================================-- Author: JKhuang-- Create date: 08/16/2012-- Description: Creates stored procedure to insert-- data into table jk_users-- =============================================ALTER PROCEDURE [dbo][SP_Insert_jk_users] @user_login varchar(60) @user_pass varchar(64) @user_nicename varchar(50) @user_email varchar(100) @user_url varchar(100) @user_activation_key varchar(60) @user_status int @display_name varchar(250) ASBEGIN SET NOCOUNT ON;-- The stored procedure allows SQL server to avoid virtually all parser workINSERT INTO jk_users (user_login user_pass user_nicename user_email user_statusdisplay_name user_url user_activation_key user_registered) VALUES (@user_login @user_pass @user_nicename @user_email @user_status @display_name @user_url @user_activation_key GETDATE());END上面我们定义了储备过程SP_Insert_jk_users向表中插入数据当我们重新执行代码时发现数据插入的时间缩短为67401秒图3数据写入时间使用数据库事务想想数据是否可以延长写入到数据库中是否可以批量地写入呢如果答应延迟一段时间才写入到数据库中那么我们可以使用Transaction来延迟数据写入数据库事务是数据库治理系统执行过程中的一个逻辑单位由一个有限的数据库操作序列构成 SQL Server确保事务执行成功后数据写入到数据库中反之事务将回滚如果我们对数据库进行十次独立的操作那么SQL Server就需要分配十次锁开销但如果把这些操作都封装在一个事务中那么SQL Server只需要分配一次锁开销 //// calc insert 10000 records consume time var sw = StopwatchStartNew(); //// Creates a database connection using (var conn = new SqlConnection(ConfigurationManagerConnectionStrings["SQLCONN2"]ToString())) { connOpen(); int cnt = 0; SqlTransaction trans = connBeginTransaction(); while (cnt++ < 10000) { using (var cmd = new SqlCommand("SP_Insert_jk_users" conn)) { //// Parameterized SQL to defense injection attacks cmdCommandType = CommandTypeStoredProcedure; //// Uses transcation to batch insert data //// To avoid lock and connection overhead cmdTransaction = trans; cmdParametersAdd("@user_login" userLogin); cmdParametersAdd("@user_pass" userPass); cmdParametersAdd("@user_nicename" userNicename); cmdParametersAdd("@user_email" userEmail); cmdParametersAdd("@user_status" userStatus); cmdParametersAdd("@display_name" displayName); cmdParametersAdd("@user_url" userUrl); cmdParametersAdd("@user_activation_key" userActivationKey); cmdExecuteNonQuery(); } } //// If no exception commit transcation transCommit(); } swStop();}图4 数据写入时间使用SqlBulkCopy通过使用事务封装了写入操作当我们重新运行代码发现数据写入的速度大大提高了只需45109秒由于一个事务只需分配一次锁资源减少了分配锁和数据库联接的耗时当然我们可以也使用SqlBulkCopy实现大量数据的写入操作具体实现代码如下:var sw = StopwatchStartNew();//// Creates a database connectionusing (var conn = new SqlConnection(ConfigurationManagerConnectionStrings["SQLCONN2"]ToString())){ connOpen(); using (var bulkCopy = new SqlBulkCopy(conn)) { //// Maping the data columns bulkCopyColumnMappingsAdd("user_login" "user_login"); bulkCopyColumnMappingsAdd("user_pass" "user_pass"); bulkCopyColumnMappingsAdd("user_nicename" "user_nicename"); bulkCopyColumnMappingsAdd("user_email" "user_email"); bulkCopyColumnMappingsAdd("user_url" "user_url"); bulkCopyColumnMappingsAdd("user_registered" "user_registered"); bulkCopyColumnMappingsAdd("user_activation_key" "user_activation_key"); bulkCopyColumnMappingsAdd("user_status" "user_status"); bulkCopyColumnMappingsAdd("display_name" "display_name"); bulkCopyDestinationTableName = "dbojk_users"; //// Insert data into datatable bulkCopyWriteToServer(dataRows); } swStop();}图5 数据写入时间上面我们通过事务和SqlBulkCopy实现数据批量写入数据库中但事实上每次我们调用cmdExecuteNonQuery()方法都会产生一个往返消息从客户端应用程序到数据库中所以我们想是否存在一种方法只发送一次消息就完成写入的操作呢使用表参数如果大家使用SQL Server 2008它提供一个新的功能表变量(Table Parameters)可以将整个表数据汇集成一个参数传递给存储过程或SQL语句它的注意性能开销是将数据汇集成参数(O(数据量))现在我们修改之前的代码在SQL Server中定义我们的表变量具体定义如下:-- =============================================-- Author: JKhuang-- Create date: 08/16/2012-- Description: Declares a user table paramter-- =============================================CREATE TYPE jk_users_bulk_insert AS TABLE ( user_login varchar(60) user_pass varchar(64) user_nicename varchar(50) user_email varchar(100) user_url varchar(100) user_activation_key varchar(60) user_status int display_name varchar(250))上面我们定义了一个表参数jk_users_bulk_insert接着我们定义一个存储过程接受表参数jk_users_bulk_insert具体定义如下:-- =============================================-- Author: JKhuang-- Create date: 08/16/2012-- Description: Creates a stored procedure receive-- a jk_users_bulk_insert argument-- =============================================CREATE PROCEDURE sp_insert_jk_users @usersTable jk_users_bulk_insert READONLY ASINSERT INTO jk_users (user_login user_pass user_nicename user_email user_url user_activation_key user_status display_name user_registered) SELECT user_login user_pass user_nicename user_email user_url user_activation_key user_status display_name GETDATE() FROM @usersTable接下我们在客户端代码中调用存储过程并且将表作为参数方式传递给存储过程var sw = StopwatchStartNew();using (var conn = new SqlConnection(ConfigurationManagerConnectionStrings["SQLCONN2"]ToString())){ connOpen(); //// Invokes the stored procedure using (var cmd = new SqlCommand("sp_insert_jk_users" conn)) { cmdCommandType = CommandTypeStoredProcedure; //// Adding a "structured" parameter allows you to insert tons of data with low overhead var param = new SqlParameter("@userTable" SqlDbTypeStructured) { Value = dt }; cmdParametersAdd(param); cmdExecuteNonQuery(); }}swStop();现在我们重新执行写入操作发现写入效率与SqlBulkCopy相当113 总结本文通过博客系统用户表设计的例子介绍我们在设计过程中容易犯的错误和代码的缺陷例如:SQL注入、数据库资源释放等问题;进而使用一些常用的代码优化技巧对代码进行优化并且通过分析数据库写入的性能开销(连接时间、解析器、数据库连接、约束处理、VARCHAR和磁盘IO)我们使用存储过程、数据库事务、SqlBulkCopy和表参数等方式降低数据库的开销参考[1] http://beginner-sql-tutorialcom/sql-query-tuninghtm[2] http://wwwdzonecom/links/r/sql_optimization_tipsquestionshtml[3] http://blackrabbitcodernet/archive/2010/11/11/cnet-little-wonders---a-presentationaspx[4] http://wwwaltdevblogadaycom/2012/05/16/sql-server-high-performance-inserts/36%和8.该公司计划在3~5年内使白兰地销售规模达到葡萄酒销售规模的60%。
领域驱动设计的一个重要的概念是领域模型,92lcom管家婆,不要说准确找到Bug所在的位置,微苦,宜养心健脾,全流程溯源排除"信任"难题业界分析认为,阿里巴巴表示。