单数据库,多数据库,单实例,多实例不同情况下的数据访问效率测试

简介:

最近公司的项目准备优化一下系统的性能,希望在数据库方面看有没有提升的空间,目前压力测试发现数据库服务器压力还不够大,Web服务器压力也不是很大的情况下,前台页面访问却很慢,看有没有办法充分利用数据库服务器的性能,于是做了一个单数据库,多数据库,单实例,多实例不同情况下的数据访问效率测试。

 

测试环境:

  • CPU:Inter Core2 Quad,Q8300,2.50GHz;
  • 内存:4.00GB
  • 系统:Windows 7 32位系统
  • 数据库系统:SqlServer 2008,有两个实例,一个是默认实例,一个是命名实例QE2 

  

测试数据:

67万真实的基金收益数据,将这个表的数据放到了3个数据库中,详细内容见下面的连接字符串配置:

 

     < add  name  ="Ins1_DB1"  connectionString  ="Data Source=.;Initial Catalog=TestDB;Integrated Security=True" />
    
< add  name  ="Ins1_DB2"  connectionString  ="Data Source=.;Initial Catalog=LocalDB;Integrated Security=True" />
    
< add  name  ="Ins2_DB"  connectionString  ="Data Source=.\QE2;Initial Catalog=TestDB;Integrated Security=True" />

 

测试内容:

首先筛选出表中所有的基金代码,然后统计每只基金的最新收益率日期,对应的T-SQL代码如下:

 

复制代码
    
  
declare   @max_fsrq   datetime
  
declare   @currJJDM   varchar ( 10 )
  
declare   @temp   table  (jjdm2  varchar ( 10 ))
  
declare   @useTime   datetime
  
set   @useTime   = GETDATE  ();
  
  
insert   into   @temp (jjdm2)
   
select  jjdm  from   [ FundYield ]   group   by  jjdm  order   by  jjdm  asc
   
  
while   EXISTS  ( select  jjdm2  from   @temp )
  
begin
    
set   @currJJDM = ( select   top   1  jjdm2  from   @temp )
    
select   @max_fsrq   =   MAX (fsrq)  from   [ FundYield ]   where  jjdm = @currJJDM
    
delete   from   @temp   where  jjdm2  = @currJJDM  
    
print   @max_fsrq
  
end
  

print   ' T-SQL Execute Times(ms): '   
 
print   datediff (ms, @useTime , getdate ())
复制代码

直接执行这个T-SQL脚本,在数据库表没有索引的情况下,耗费的时间是: 

T-SQL Execute Times(ms):
58796

 

根据这个功能,写了一个.net控制台程序来测试,测试程序没有使用任何数据访问框架,直接使用ADO.NET,下面是多线程测试的代码,其它代码略:

 

复制代码
  public   static   void  Test2( string  connName1, string  connName2)
        {
            System.Diagnostics.Stopwatch watch 
=   new  System.Diagnostics.Stopwatch();
            watch.Start();
            
string  allJjdmList  =   "" ;
            
string  connString  =  getConnectionString();
            
// SqlConnection conn = new SqlConnection(connString);
            
// conn.Open();

            
string  sql  =   " select jjdm from [FundYield] group by jjdm order by jjdm asc " ;
            DataSet ds 
=  getData(connString, sql);
            
int  allCount  =  ds.Tables[ 0 ].Rows.Count;
            
int  p  =  ( int )(allCount  *   0.5 );

            System.Threading.Thread t1
= new  System.Threading.Thread ( new  System.Threading.ParameterizedThreadStart (tp1 =>
                {
                    
for  ( int  i  =   0 ; i  <  p; i ++ )
                    {
                        
string  jjdm  =  ds.Tables[ 0 ].Rows[i][ 0 ].ToString();

                        
object  result  =  getSclar(ConfigurationManager.ConnectionStrings[connName1].ConnectionString,
                       
string .Format( " select MAX(fsrq) from [FundYield] where jjdm='{0}' " , jjdm));
                        
if  (result  !=  DBNull.Value)
                        {
                            DateTime dt 
=  Convert.ToDateTime(result);
                            
// Console.WriteLine("Thread 2 No {0} ,jjdm[{1}] last FSRQ is:{2}", i, jjdm, dt);
                        }

                        allJjdmList 
=  allJjdmList  +   " , "   +  jjdm;
                    }

                    Console.WriteLine(
" Tread 1 used all time is(ms):{0} " , watch.ElapsedMilliseconds);
                }
            ));

            System.Threading.Thread t2 
=   new  System.Threading.Thread( new  System.Threading.ParameterizedThreadStart(tp2  =>
            {
                
for  ( int  i  =  p; i  <  allCount; i ++ )
                {
                    
string  jjdm  =  ds.Tables[ 0 ].Rows[i][ 0 ].ToString();
                    
// 这里不论使用default还是express,区别不大
                     object  result  =  getSclar(ConfigurationManager.ConnectionStrings[connName2].ConnectionString,
                        
string .Format( " select MAX(fsrq) from [FundYield] where jjdm='{0}' " , jjdm));
                    
if  (result  !=  DBNull.Value)
                    {
                        DateTime dt 
=  Convert.ToDateTime(result);
                        
// Console.WriteLine("Thread 2 No {0} ,jjdm[{1}] last FSRQ is:{2}", i, jjdm, dt);
                    }
                    
                    allJjdmList 
=  allJjdmList  +   " , "   +  jjdm;
                }

                Console.WriteLine(
" Tread 2 used all time is(ms):{0} " , watch.ElapsedMilliseconds);
            }
            ));

            t1.Start();
            t2.Start();
            t1.Join();
            t2.Join();

            Console.WriteLine(
" ====All thread completed!======== " );

        }
复制代码

 

 

下面是测试结果:

第一次,数据库没有创建索引,进行全表扫描:

 

------单数据库,单线程测试---------
used all time is(ms):59916
------同一实例,双数据库,单线程测试---------
used all time is(ms):59150
------同一实例,双数据库,多线程测试---------
Tread 2 used all time is(ms):51223
Tread 1 used all time is(ms):58175
====All thread completed!========
------双实例,双数据库,单线程测试---------
used all time is(ms):58230
------双实例,双数据库,多线程测试---------
Tread 2 used all time is(ms):52705
Tread 1 used all time is(ms):58293
====All thread completed!========

 

 

 

 

 

 

 

 

 

 

 

 

 

第二次,数据库响应的字段创建索引,下面是测试结果:

 


------单数据库,单线程测试---------
used all time is(ms):1721
------同一实例,双数据库,单线程测试---------
used all time is(ms):1737
------同一实例,双数据库,多线程测试---------
Tread 2 used all time is(ms):1684
Tread 1 used all time is(ms):1714
====All thread completed!========
------双实例,双数据库,单线程测试---------
used all time is(ms):1874


------单数据库,单线程测试---------
used all time is(ms):1699
------同一实例,双数据库,单线程测试---------
used all time is(ms):1754
------同一实例,双数据库,多线程测试---------
Tread 1 used all time is(ms):1043
Tread 2 used all time is(ms):1103
====All thread completed!========
------双实例,双数据库,单线程测试---------
used all time is(ms):1838
------双实例,双数据库,多线程测试---------
Tread 1 used all time is(ms):1072
Tread 2 used all time is(ms):1139
====All thread completed!========

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

测试结论:

综合全表扫描访问和有索引方式的访问,

单线程访问:

  • 在同一个数据库实例上,双数据库没有体现出优势,甚至单数据库稍微优胜于多数据库;
  • 在两个数据库实例上,双实例双实例要落后于单实例单数据库;

多线程访问:

  • 双数据库实例稍微落后于单数据库实例;

 

综合结论,看来不论是双数据库还是双实例,对比与单实例或者单数据库,都没有体现出优势,看来前者的优势不在于访问效率,一位朋友说,数据库实例是不同的服务,控制粒度更小,维护影响比较低。但我想,双数据库实例,双数据库,多核CPU,应该跟两台数据库服务器差不多的性能吧,怎么没有体现优势呢?也许是我的测试机器仅仅有一个磁盘,这里磁盘IO成了瓶颈。

 

这个测试有没有意义,或者这个结果的原因,还请大牛们多多指教!

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

意外发现:

1,有人说频繁的查询在完全数据库中进行效率最高,测试发现,在查询分析器上直接运行上面的那个T-SQL脚本,跟程序从数据库取出数据,再加工计算查询,效率上没有明显的区别,所以哪些支持“将复杂的业务逻辑写在存储过程中效率最高的观点是站不住脚的!”  ,ADO.NET从数据库来回操作数据一样有效率,如果加上复杂的字符函数计算和大批量的循环操作,存储过程的效率不一定高。

 

2,在使用程序进行频繁的数据库操作的时候,使用一个连接对象还是在每个方法中使用新的连接对象,一直是很纠结的问题,心想频繁的数据操作还是用一个连接对象快吧?在本文给出的测试代码中,有下列语句:

//SqlConnection conn = new SqlConnection(connString);
            
//conn.Open();
注释掉这些语句,在被调用的方法中使用自己的连接对象,与取消注释,全部使用一个连接对象,效率上没有任何区别!

究其原因,可能是ADO.NET自动使用了连接池,实际上程序在不同的情况下,使用的都是一个连接,所以操作上效率没有区别。

 

后续测试

在真正的服务器上进行测试,发现测试结论又不一样,我们有服务器A,拥有16个核,32G内存,另外一台服务器B,拥有8个核,16G内存。在服务器A上有一个SqlServer实例,两个一样的数据库;在在服务器B上有一个SqlServer实例,一个数据库,下面是测试结果:

------单数据库,单线程测试---------
used all time is(ms):650
------同一实例,双数据库,单线程测试---------
used all time is(ms):418
------同一实例,双数据库,多线程测试---------
Tread 2 used all time is(ms):221
Tread 1 used all time is(ms):223
====All thread completed!========
------双实例,双数据库,单线程测试---------
used all time is(ms):1283
------双实例,双数据库,多线程测试---------
Tread 1 used all time is(ms):228
Tread 2 used all time is(ms):542
====All thread completed!========

可以看到,同一实例,多数据库,还是有明显的优势,而多线程优势更大;由于两台服务器性能差距较大,双实例测试没有显示出优势,但多线程下还是比单实例单数据库好!

为什么PC机跟服务器测试的结论不一致?也许还是跟计算能力相关,PC机的计算负载太大,已经失去了测试的意义。

 

 


    本文转自深蓝医生博客园博客,原文链接:http://www.cnblogs.com/bluedoctor/archive/2011/06/28/2092113.html,如需转载请自行联系原作者



相关文章
|
1月前
|
存储 Oracle 关系型数据库
Dataphin常见问题之想要周期执行任务如何解决
Dataphin是阿里云提供的一站式数据处理服务,旨在帮助企业构建一体化的智能数据处理平台。Dataphin整合了数据建模、数据处理、数据开发、数据服务等多个功能,支持企业更高效地进行数据治理和分析。
|
23天前
|
存储 NoSQL Java
Java数据库编程指南:实现高效数据存储与访问
【4月更文挑战第2天】Java开发者必须掌握数据库编程,尤其是JDBC,它是连接数据库的标准接口。使用Spring JDBC或JPA能简化操作。选择合适的JDBC驱动,如MySQL Connector/J,对性能至关重要。最佳实践包括事务管理、防SQL注入、优化索引和数据库设计。NoSQL数据库如MongoDB也日益重要,Java有对应的驱动支持。理解这些概念和技术是构建高效数据库应用的基础。
Java数据库编程指南:实现高效数据存储与访问
|
1天前
|
SQL 关系型数据库 MySQL
stream-query多数据库进行CI测试
stream-query多数据库进行CI测试
7 0
|
1天前
|
关系型数据库 MySQL 数据库
一台MySQL数据库启动多个实例
一台MySQL数据库启动多个实例
|
2天前
|
存储 SQL 数据库
数据库库表结构设计:原理、实例与最佳实践
数据库库表结构设计:原理、实例与最佳实践
13 0
|
7天前
|
存储 关系型数据库 MySQL
如何处理爬取到的数据,例如存储到数据库或文件中?
处理爬取的数据,可存储为txt、csv(适合表格数据)或json(适合结构化数据)文件。若需存储大量数据并执行复杂查询,可选择关系型(如MySQL)或非关系型(如MongoDB)数据库。以MySQL为例,需安装数据库和Python的pymysql库,创建数据库和表,然后编写Python代码进行数据操作。选择存储方式应考虑数据类型、数量及后续处理需求。
14 1
|
8天前
|
SQL 关系型数据库 MySQL
关系型数据库插入数据的语句
使用SQL的`INSERT INTO`语句向关系型数据库的`students`表插入数据。例如,插入一个`id`为1,`name`为&#39;张三&#39;,`age`为20的记录:`INSERT INTO students (id, name, age) VALUES (1, &#39;张三&#39;, 20)。如果`id`自增,则可简化为`INSERT INTO students (name, age) VALUES (&#39;张三&#39;, 20)`。
10 2
|
8天前
|
SQL 存储 Oracle
关系型数据库查询数据的语句
本文介绍了关系型数据库中的基本SQL查询语句,包括选择所有或特定列、带条件查询、排序、分组、过滤分组、表连接、限制记录数及子查询。SQL还支持窗口函数、存储过程等高级功能,是高效管理数据库的关键。建议深入学习SQL及相应数据库系统文档。
9 2
|
9天前
|
SQL 缓存 Java
Java数据库连接池:优化数据库访问性能
【4月更文挑战第16天】本文探讨了Java数据库连接池的重要性和优势,它能减少延迟、提高效率并增强系统的可伸缩性和稳定性。通过选择如Apache DBCP、C3P0或HikariCP等连接池技术,并进行正确配置和集成,开发者可以优化数据库访问性能。此外,批处理、缓存、索引优化和SQL调整也是提升性能的有效手段。掌握数据库连接池的使用是优化Java企业级应用的关键。
|
15天前
|
人工智能 Cloud Native 算法
数据之势丨AI时代,云原生数据库的最新发展趋势与进展
AI与云数据库的深度结合是数据库发展的必然趋势,基于AI能力的加持,云数据库未来可以实现更快速的查询和决策,帮助企业更好地利用海量数据进行业务创新和决策优化。
数据之势丨AI时代,云原生数据库的最新发展趋势与进展

热门文章

最新文章