【发布时间】:2018-12-24 19:52:53
【问题描述】:
我有一个存储过程,当我在 SQL Server 中运行查询时,我在 2 秒内得到结果,但是当我从程序中调用该过程时,需要 40 秒。
调用过程时如何加快程序的运行速度?
存储过程代码:
CREATE PROC [dbo].[SearchOrdersPrice]
@Criteria VARCHAR(50)
AS
SELECT
[Lab_Orders].ORDER_ID AS 'Order Number',
[ORDER_DATE] AS 'Order Date',
Patients.Patient_Name AS 'Patient Name',
Patients.Age AS 'Patient Age',
LabTests.TestName AS 'Test Name',
Customers.CustName AS 'Customer Name',
Invoice_order_no AS 'Request Form Number',
[ORDER_DESCRIPTION] AS 'Diagnosis',
Lab_Orders.USER_ID AS 'Requested By User',
Order_Details.TOTAL_AMOUNT AS 'Total Amount'
FROM
Lab_Orders
INNER JOIN
Order_Details ON Order_Details.ORDER_ID = Lab_Orders.ORDER_ID
INNER JOIN
Customers ON Customers.CustId = Lab_Orders.CUSTID
INNER JOIN
patients ON Patients.Patient_No = Lab_Orders.patient_no
INNER JOIN
LabTests ON LabTests.TestId = Order_Details.TESTID
WHERE
CONVERT(VARCHAR, [Lab_Orders].ORDER_ID) + CONVERT(VARCHAR, [ORDER_DATE]) + CustName + ORDER_DESCRIPTION + TestName + USER_ID + PATIENT_NAME + CONVERT(VARCHAR, AGE) + Invoice_order_no + TOTAL_AMOUNT LIKE '%'+ @Criteria +'%'
AND Lab_Orders.order_status = 1
ORDER BY
[Lab_Orders].ORDER_ID DESC
我的 C#(Windows 窗体代码):按下按钮时,我有一个按钮,我调用另一个窗口并调用过程并获取数据。
按钮处理程序代码:
private void btnSelectOrder_Click(object sender, EventArgs e)
{
checkvalue = checkCASH.Checked;
VIEW_ORDER_DETAILS orders = new VIEW_ORDER_DETAILS();
orders.ShowDialog();
if (checkCASH.Checked == true)
{
try
{
cashPatient = 1;
this.txtOrder.Text = orders.OrdersDataGridView.CurrentRow.Cells[0].Value.ToString();
txtOrder.Focus();
}
catch
{
MessageBox.Show("Select Order Number");
}
}
if (checkCASH.Checked == false)
{
try
{
cashPatient = 2;
this.txtOrder.Text = orders.OrdersDataGridView.CurrentRow.Cells[0].Value.ToString();
txtOrder.Focus();
}
catch
{
MessageBox.Show("Select Order Number");
}
}
}
其他窗口页面加载代码:
public VIEW_ORDER_DETAILS()
{
InitializeComponent();
this.Size = new Size(1700, 600);
if (LAB_SAMPLES.checkvalue == true)
{
OrdersDataGridView.DataSource = order.SearchOrdersPricecash("");
}
else
{
OrdersDataGridView.DataSource = order.SearchOrdersPrice("");
}
}
这是调用方法:
public DataTable SearchOrdersPrice(string order_id)
{
DAL.DataAccessLayer DAL = new DAL.DataAccessLayer();
DataTable dt = new DataTable();
SqlParameter[] param = new SqlParameter[1];
param[0] = new SqlParameter("@Criteria", SqlDbType.VarChar, 50);
param[0].Value = order_id;
dt = DAL.SelectData("SearchOrdersPrice", param);
DAL.close();
return dt;
}
这是 DAL 代码:
class DataAccessLayer
{
SqlConnection sqlconnection;
// this initialize the connection to the database
public DataAccessLayer()
{
sqlconnection = new SqlConnection(@"");
}
// method to open the connection
public void open()
{
if (sqlconnection.State != ConnectionState.Open)
{
sqlconnection.Open();
}
}
// method to close the connection
public void close()
{
if (sqlconnection.State == ConnectionState.Open)
{
sqlconnection.Close();
}
}
// method to read data from database
public DataTable SelectData(string stored_procedure, SqlParameter[] param)
{
SqlCommand sqlcmd = new SqlCommand();
sqlcmd.CommandType = CommandType.StoredProcedure;
sqlcmd.CommandText = stored_procedure;
sqlcmd.Connection = sqlconnection;
if (param != null)
{
for (int i = 0; i < param.Length; i++)
{
sqlcmd.Parameters.Add(param[i]);
}
}
SqlDataAdapter da = new SqlDataAdapter(sqlcmd);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
// Method to insert update and delete date from database
public void ExecuteCommand (string stored_procedure , SqlParameter[] param)
{
SqlCommand sqlcmd = new SqlCommand();
sqlcmd.CommandType = CommandType.StoredProcedure;
sqlcmd.CommandText = stored_procedure;
sqlcmd.Connection = sqlconnection;
if (param != null)
{
sqlcmd.Parameters.AddRange(param);
}
sqlcmd.ExecuteNonQuery();
}
}
我试图通过使用参数嗅探来解决我的问题,但它没有解决问题:
ALTER proc [dbo].[SearchOrdersPrice]
@Criteria varchar(50)
as
begin
declare @localCriteria varchar(50)
set @localCriteria = @Criteria
SELECT [Lab_Orders].ORDER_ID as 'Order Number'
,[ORDER_DATE] as 'Order Date'
,Patients.Patient_Name as 'Patient Name'
,Patients.Age as 'Patient Age'
,LabTests.TestName as 'Test Name'
,Customers.CustName as 'Customer Name'
,Invoice_order_no as 'Request Form Number'
,[ORDER_DESCRIPTION] as 'Diagnosis'
,Lab_Orders.USER_ID as 'Requested By User'
,Order_Details.TOTAL_AMOUNT as 'Total Amount'
FROM Lab_Orders
inner join Order_Details on Order_Details.ORDER_ID= Lab_Orders.ORDER_ID
inner join Customers on Customers.CustId = Lab_Orders.CUSTID
inner join patients on Patients.Patient_No = Lab_Orders.patient_no
inner join LabTests on LabTests.TestId = Order_Details.TESTID
where CONVERT(varchar,[Lab_Orders].ORDER_ID) + CONVERT(varchar,[ORDER_DATE]) + CustName+ORDER_DESCRIPTION+TestName+
+ USER_ID + PATIENT_NAME + CONVERT (varchar,AGE)+Invoice_order_no+TOTAL_AMOUNT like '%'+ @localCriteria +'%'
and Lab_Orders.order_status=1
order by [Lab_Orders].ORDER_ID desc
end
然后我从存储过程中删除了参数,在调用过程时仍然需要 40 秒:
ALTER proc [dbo].[SearchOrdersPrice]
as
SELECT [Lab_Orders].ORDER_ID as 'Order Number'
,[ORDER_DATE] as 'Order Date'
,Patients.Patient_Name as 'Patient Name'
,Patients.Age as 'Patient Age'
,LabTests.TestName as 'Test Name'
,Customers.CustName as 'Customer Name'
,Invoice_order_no as 'Request Form Number'
,[ORDER_DESCRIPTION] as 'Diagnosis'
,Lab_Orders.USER_ID as 'Requested By User'
,Order_Details.TOTAL_AMOUNT as 'Total Amount'
FROM Lab_Orders
inner join Order_Details on Order_Details.ORDER_ID= Lab_Orders.ORDER_ID
inner join Customers on Customers.CustId = Lab_Orders.CUSTID
inner join patients on Patients.Patient_No = Lab_Orders.patient_no
inner join LabTests on LabTests.TestId = Order_Details.TESTID
where Lab_Orders.order_status=1
order by [Lab_Orders].ORDER_ID desc
【问题讨论】:
-
考虑使用像 Dapper 这样的微 ORM,而不是这种旧的、过时的 ADO 代码。
-
您还没有为您的 DAL 提供代码,所以我们不知道里面发生了什么。
-
@Robert Harvey,如何使用微 ORM?我添加了完整的 DAL 代码
-
您的问题将是
DataAdapter.Fill(DataTable)电话。如前所述,这个古老的代码应该被扔掉,取而代之的是更简单、更快的东西,比如 Dapper。
标签: c# sql-server