我已经以编程方式创建了RadGrid
,并使用NeedDataSource
-> GetDataTable
对其进行了绑定(bind)。
在GetDataTable
内,我正在调用connstring并使用适配器填充网格(请参见下面的代码)。问题是,在我的SQL Server中,查询需要0秒钟才能运行,但是在ASP.NET Debug模式下,查询大约需要3到5秒钟,在我的页面上有很多RadGrid的情况下,这导致了我页面加载缓慢。adapter.Fill
的这种处理速度是否是一个普遍问题,或者我在设置上做错了什么? (即conn.open/close或其他命令)?
public DataTable GetDataTable(int Year, int month, string datatype)
{
String ConnString = ConfigurationManager.ConnectionStrings["IHG_MSTConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(ConnString);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand("[Yield_Planner_With_Strategy]", conn);
adapter.SelectCommand.CommandType = System.Data.CommandType.StoredProcedure;
adapter.SelectCommand.Parameters.AddWithValue("@Holidex_Code", RadComboBox_Hotels.SelectedValue);
adapter.SelectCommand.Parameters.AddWithValue("@Event_Year", Year);
adapter.SelectCommand.Parameters.AddWithValue("@Event_Month", month);
adapter.SelectCommand.Parameters.AddWithValue("@DataType", datatype);
adapter.SelectCommand.Parameters.AddWithValue("@MktSeg", Fruitful.Get_Checked_Values_As_CSV(RadComboBox_MktSeg));
string exportdate = DateTime.Now.ToString("yyyy/MM/dd");
if (RadComboBox_ExportTimeStamp.Text != "" && RadComboBox_ExportTimeStamp.Text != "Create New Strategy")
{ exportdate = Convert.ToDateTime(RadComboBox_ExportTimeStamp.Text).ToString("yyyy/MM/dd"); }
adapter.SelectCommand.Parameters.AddWithValue("@ExportTimeStamp", exportdate);
DataTable myDataTable = new DataTable();
conn.Open();
try
{
adapter.Fill(myDataTable);
}
finally
{
conn.Close();
}
return myDataTable;
}
最佳答案
为什么将字符串用作ExportTimeStamp
参数?采用DateTime
(如果是date
或datetime
列)。
我也将您对 AddWithValue
的所有调用替换为 Add
。当您调用AddWithValue
时,必须猜测参数的类型。如果猜错了,优化器将无法选择正确的索引并退回到表扫描,这证明了数据库性能的核心。AddWithVaue
可能会导致多个查询计划。由于.NET不知道数据库列的大小,因此它将使用变量的大小。因此,如果您有一个参数化查询并传入两个长度为10的字符串,另一个为长度20的字符串,则将获得两个计划:@text nvarchar(10)
和@text nvarchar(20)
。当它的字段可能是nvarchar
时,它还将假定您的字段是varchar
,并且您将获得隐式转换。
因此,总是将正确的类型传递给AddWithValue
,或者(更好)使用具有正确的类型和大小的 SqlParameterCollection.Add
。它还将在将参数发送到数据库之前对其进行验证。
有关的:
另外,使用
using
-statement以确保连接完成后立即关闭连接,即使发生错误也是如此。这是一个例子:
public DataTable GetDataTable(int Year, int month, string datatype)
{
DataTable myDataTable = new DataTable();
String ConnString = ConfigurationManager.ConnectionStrings["IHG_MSTConnectionString"].ConnectionString;
using(SqlConnection conn = new SqlConnection(ConnString))
using (SqlDataAdapter adapter = new SqlDataAdapter())
{
var cmd = new SqlCommand("[Yield_Planner_With_Strategy]", conn);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add("@Holidex_Code", SqlDbType.Int).Value = int.Parse(RadComboBox_Hotels.SelectedValue);
cmd.Parameters.Add("@Event_Year", SqlDbType.Int).Value = Year;
cmd.Parameters.Add("@Event_Month", SqlDbType.Int).Value = month;
cmd.Parameters.Add("@DataType", SqlDbType.VarChar).Value = datatype;
cmd.Parameters.Add("@MktSeg", SqlDbType.NVarChar).Value = Fruitful.Get_Checked_Values_As_CSV(RadComboBox_MktSeg);
DateTime exportdate = DateTime.Now;
if (RadComboBox_ExportTimeStamp.Text != "" && RadComboBox_ExportTimeStamp.Text != "Create New Strategy")
{
exportdate = DateTime.Parse(RadComboBox_ExportTimeStamp.Text);
}
cmd.Parameters.Add("@ExportTimeStamp", SqlDbType.DateTime).Value = exportdate;
adapter.SelectCommand = cmd;
// you don't need to open it with Fill
adapter.Fill(myDataTable);
}
return myDataTable;
}