我的MS SQL Server查询使用了大量的子查询,当在具有近10000000的大数据的服务器上运行时,执行就像永远一样。我需要一种更好的方法来重构查询以使其更快。
这是查询:
<?php
$query = "SELECT ".$limitresult." * FROM customer c INNER JOIN (SELECT MIN(ac_no) ac_no
FROM loans where full_paid ='0' GROUP BY ac_no) AS l ON c.cust_no = l.ac_no and
cust_type = 'BUS' ".$branchid." ".$accnos." ";
$check = @sqlsrv_query($conn, $query);
$i = 1;
while($rows = @sqlsrv_fetch_array( $check, SQLSRV_FETCH_ASSOC)) {
$que22 = "select * from company";
$checks22 = sqlsrv_query($conn, $que22);
$row22 = @sqlsrv_fetch_array($checks22, SQLSRV_FETCH_ASSOC);
$comi = $row22['branch'];
$ques = "select BRSES_DATE from company";
$checks22y = sqlsrv_query($conn, $ques);
$row22y = sqlsrv_fetch_array($checks22y, SQLSRV_FETCH_ASSOC);
$dat = @$row22y['BRSES_DATE']->format('Y-m-d H:m:i');
$iu = $rows['cust_no'];
$qur = "SELECT Member.Branch,Member.GL_No,Member.Ac_NO,Member.BRANCH+Member.GL_NO+Member.AC_NO AS BRGLAC,Customer.Cust_No,Customer.Name,Group_Name,ID_CARD,Subgroup as subgroup2,Cust_Type,Cust_Sex,Cust_Cat,Area_Code,Cust_Type,Dobirth,Address,Ref_No,Bank_VNO,Cust_Ca2,nType,Group_Code FROM Member INNER JOIN CUSTACC ON Member.Branch = CustAcc.Branch AND cust_no='$iu' AND Member.GL_NO = CustACC.GL_No AND Member.AC_NO = CustACC.AC_No INNER JOIN Customer ON Member.Branch = Customer.Branch AND Member.Cust_No = Customer.Cust_No WHERE CUSTACC.Exp_Date < '$dat' AND Member.Branch = '$comi' AND MEMBER.Gl_NO IN (SELECT Coa.GL_NO FROM Coa WHERE Product = 'S' )";
$che = sqlsrv_query($conn, $qur);
$roe = @sqlsrv_fetch_array($che, SQLSRV_FETCH_ASSOC);
$c = $rows['cust_no'];
$ret ="select * from fssign where cust_no='$c'";
$c = sqlsrv_query($conn, $ret);
$r = sqlsrv_fetch_array($c, SQLSRV_FETCH_ASSOC);
//$cod = $r['bus_type'];
?>
答案 0 :(得分:0)
不了解您的基表以及您遇到问题的确切查询,我建议的一个改进是使用存储过程动态构建查询而不是在php中构建它。并确保使用sp_executesql系统存储过程来执行动态t-sql查询,这将使您从参数化执行计划中受益。
对于你问题中的第一个t-sql语句,我会写一个像这样的proc ...
CREATE PROCEDURE usp_MySpsNameBLabla
@LimitResults INT = NULL
, @BranchID INT = NULL
, @AccountNo INT = NULL
AS
BEGIN
SET NOCOUNT ON;
Declare @Sql NVARCHAR(MAX);
SET @Sql = N'SELECT ' + CASE WHEN @LimitResults IS NOT NULL
THEN N' TOP (@LimitResults) ' ELSE N' ' END
+ N' *
FROM customer c
INNER JOIN (
SELECT MIN(ac_no) ac_no
FROM loans
where full_paid =''0''
GROUP BY ac_no
) AS l ON c.cust_no = l.ac_no
WHERE c.cust_type = ''BUS'''
+ CASE WHEN @BranchID IS NOT NULL
THEN N' AND c.BranchID = @BranchID ' ELSE N' ' END
+ CASE WHEN @AccountNo IS NOT NULL
THEN N' AND c.ac_no = @AccountNo ' ELSE N' ' END
Exec sp_executesql @sql
,N'@LimitResults INT ,@BranchID INT , @AccountNo INT '
,@LimitResults
,@BranchID
,@AccountNo
END