ADO.NET SQL Server性能瓶颈 [英] ADO.NET SQL Server Performance bottleneck

查看:155
本文介绍了ADO.NET SQL Server性能瓶颈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个SQL连接,我不得不从第二个500到10000倍随时随地访问数据库。经过约250每秒事情开始放慢脚步,然后应用程序远远落后崩溃得到。



我在想将数据库置于一本字典。我需要最快的性能,我可以得到。目前ado.net大约需要1至2毫秒,但事情发生,导致了瓶颈。



这有什么错用下面的语法每秒10K的查询?是一本字典去上班?我们正在谈论大约12万条记录,我需要能够在1至5毫秒搜索。我也有另外一个集合中已有50万条记录,所以我不知道如何来存储它的数据库。任何建议将是巨大的。



SQL数据库有128 GB的内存和80个处理器和应用程序是SQL Server 2012年

$ B在同一台服务器上
$ b

 使用(SqlConnection的sqlconn =新的SqlConnection(sqlConnection.SqlConnectionString()))
{
使用(的SqlCommand SQLCMD =新的SqlCommand( sqlconn))
{
sqlcmd.CommandType = System.Data.CommandType.StoredProcedure;
sqlcmd.Parameters.Clear();
sqlcmd.CommandTimeout = 1;
sqlconn.Open();
使用(SqlDataReader的sqlDR = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection))


公共静态字符串SqlConnectionString()
{
返回的String.Format( 数据源= {0},{1};初始目录= {2};用户ID = {3};密码= {4};应用程序名称= {5};异步处理= TRUE; MultipleActiveResultSets = TRUE;最大池大小= 524;池= TRUE;,
DataIP,端口,数据库,用户名,密码,IntanceID);
}



DataReader的下面的代码是



  r.CustomerInfo =新CustomerVariable(); 
r.GatewayRoute =新的List< RoutingGateway>();
,而(sqlDR.Read()==真)
{

如果(sqlDR [RateTableID]!= NULL)
r.CustomerInfo.RateTable = sqlDR [RateTableID]的ToString()。
如果(sqlDR [EndUserCost]!= NULL)
r.CustomerInfo.IngressCost = sqlDR [EndUserCost]的ToString()。
如果(sqlDR [管辖权]!= NULL)
r.CustomerInfo.Jurisdiction = sqlDR [管辖权]的ToString()。
如果(sqlDR [MinTime]!= NULL)
r.CustomerInfo.MinTime = sqlDR [MinTime]的ToString()。
如果(sqlDR [间隔]!= NULL)
r.CustomerInfo.interval = sqlDR [间隔]的ToString()。
如果(sqlDR [密码]!= NULL)
r.CustomerInfo.code = sqlDR [密码]的ToString()。
如果(sqlDR [BillBy]!= NULL)
r.CustomerInfo.BillBy = sqlDR [BillBy]的ToString()。
如果(sqlDR [RoundBill]!= NULL)
r.CustomerInfo.RoundBill = sqlDR [RoundBill]的ToString()。

}
sqlDR.NextResult();


解决方案

  1. 唐'T关闭并重新打开连接,你可以把它请求之间开放。即使你有连接池打开,有一定的开销,其中包括一个简短的关键部分,以防止并发问题抓住从池中连接时。不妨避免这种情况。


  2. 确保您的存储过程SET NOCOUNT ON,以减少繁琐。


  3. 确保您使用的是最小的事务隔离级别,你可以逃脱,如脏读a.k.a NOLOCK。您可以在连接级别或存储过程本身中的客户端,它曾经你更舒服设置此。


  4. 简介这些交易确保的瓶颈是在客户端上。可能是数据库服务器上或网络上。


  5. 如果这是一个多线程应用程序(例如在网络上),请检查您的连接池设置,并确保它的足够大。有此一PerfMon的计数器。


  6. 访问您的领域使用由序强类型getter方法,例如的GetString(0)或GetInt32等(3)。


  7. 扭捏的bejesus出您的存储过程和索引。可以在此写一本书。


  8. 在下跌期间重新索引你的表,并填写了索引页,如果这是一个相当静态的表。


  9. 如果存储过程的目的是检索单行,尝试加入TOP 1查询,以便第一行发现后停止寻找热塑成型。此外,考虑使用输出参数,而不是一个结果,这将产生少一点的开销。


  10. 一个字典可能工作,但它取决于数据的性质,你是如何寻找它,有多宽行是。如果你更新我将修改我的答案更多信息,你的问题。



I have a sql connection that I have to hit the database anywhere from 500 to 10,000 times a second. After about 250 per second things start to slow down and then the app gets so far behind it crashes.

I was thinking about putting the database into a dictionary. I need the fastest performance I can get. Currently the ado.net takes about 1 to 2 milliseconds but something happens that causes a bottleneck.

Is there anything wrong with the below syntax for the 10k queries per second? is a dictionary going to work? we are talking about 12 million records and I need to be able to search it within 1 to 5 milliseconds. I also have another collection in the database that has 50 million records so I'm not sure how to store it. any suggestions will be great.

The SQL db has 128 gb memory and 80 processors and the app is on the same server on the Sql server 2012

   using (SqlConnection sqlconn = new SqlConnection(sqlConnection.SqlConnectionString()))
   {
       using (SqlCommand sqlcmd = new SqlCommand("", sqlconn))
       {
           sqlcmd.CommandType = System.Data.CommandType.StoredProcedure;
           sqlcmd.Parameters.Clear();
           sqlcmd.CommandTimeout = 1;
           sqlconn.Open();
           using (SqlDataReader sqlDR = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection))


    public static string SqlConnectionString()
    {
        return string.Format("Data Source={0},{1};Initial Catalog={2};User ID={3};Password={4};Application Name={5};Asynchronous Processing=true;MultipleActiveResultSets=true;Max Pool Size=524;Pooling=true;",
                    DataIP, port, Database, username, password, IntanceID);
    }

the code below the datareader is

r.CustomerInfo = new CustomerVariable();
r.GatewayRoute = new List<RoutingGateway>();
while (sqlDR.Read() == true)
{

    if (sqlDR["RateTableID"] != null)
        r.CustomerInfo.RateTable = sqlDR["RateTableID"].ToString();
    if (sqlDR["EndUserCost"] != null)
        r.CustomerInfo.IngressCost = sqlDR["EndUserCost"].ToString();
    if (sqlDR["Jurisdiction"] != null)
        r.CustomerInfo.Jurisdiction = sqlDR["Jurisdiction"].ToString();
    if (sqlDR["MinTime"] != null)
        r.CustomerInfo.MinTime = sqlDR["MinTime"].ToString();
    if (sqlDR["interval"] != null)
        r.CustomerInfo.interval = sqlDR["interval"].ToString();
    if (sqlDR["code"] != null)
        r.CustomerInfo.code = sqlDR["code"].ToString();
    if (sqlDR["BillBy"] != null)
        r.CustomerInfo.BillBy = sqlDR["BillBy"].ToString();
    if (sqlDR["RoundBill"] != null)
        r.CustomerInfo.RoundBill = sqlDR["RoundBill"].ToString();

}
sqlDR.NextResult();

解决方案

  1. Don't close and re-open the connection, you can keep it open between requests. Even if you have connection pooling turned on, there is certain overhead, including a brief critical section to prevent concurrency issues when seizing a connection from the pool. May as well avoid that.

  2. Ensure your stored procedure has SET NOCOUNT ON to reduce chattiness.

  3. Ensure you are using the minimum transaction isolation level you can get away with, e.g. dirty reads a.k.a NOLOCK. You can set this at the client end at the connection level or within the stored procedure itself, which ever you're more comfortable with.

  4. Profile these transactions to ensure the bottleneck is on the client. Could be on the DB server or on the network.

  5. If this is a multithreaded application (e.g. on the web), check your connection pool settings and ensure it's large enough. There's a PerfMon counter for this.

  6. Access your fields by ordinal using strongly typed getters, e.g. GetString(0) or GetInt32(3).

  7. Tweak the bejesus out of your stored procedure and indexes. Could write a book on this.

  8. Reindex your tables during down periods, and fill up the index pages if this is a fairly static table.

  9. If the purpose of the stored procedure is to retrieve a single row, try adding TOP 1 to the query so that it will stop loking after the first row is found. Also, consider using output parameters instead of a resultset, which incurs a little less overhead.

  10. A dictionary could potentially work but it depends on the nature of the data, how you are searching it, and how wide the rows are. If you update your question with more information I'll edit my answer.

这篇关于ADO.NET SQL Server性能瓶颈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆