我有以下查询
SELECT MAKEDATE( LEFT(IF(i_id = 0, Job.FillDate, BillingDate), 4 ) ,
RIGHT( IF(i_id = 0, Job.FillDate, BillingDate), 3 ) ) as day,
IFNULL(ROUND(SUM(GREATEST((IF(i_id = 0 AND ISNULL(BillAmt), (PaidByPlan1+PaidByPlan2+Cashpaid), IF(ISNULL(BillAmt),(PaidByPlan1+PaidByPlan2+Cashpaid), (BillAmt+Cashpaid)))),0.00)),2),0.00) as total_pay,
Count(*) as total_transactions
FROM `job` AS `Job`
LEFT JOIN `jobtrak` AS `JobTrack` ON (
`Job`.`id` = `JobTrack`.`job_id`
AND IF(i_id = 0, `Job`.`FillDate`, BillingDate) BETWEEN 2014183 AND 2014212
AND LENGTH( CONV( Jobstatus, 10, 2 ) ) NOT IN ( 5, 6, 8 )
AND `Job`.`Active` = 0 )
GROUP BY IF(i_id = 0, `Job`.`FillDate`, BillingDate);
以下查询耗尽了我的mysql服务器并导致页面永远不会加载到我的应用程序上。所以,我查看了解释,它显示Job表正在检索所有493345条记录,JobTrack表从其表中获取所有286812条记录。为什么这样做?有什么建议??
答案 0 :(得分:1)
`Job`.`id` = `Job`.`job_id`
您正在加入同一张表中的列
答案 1 :(得分:1)
这是你的查询,清理了一下,所以我发现它更具可读性:
SELECT MAKEDATE( LEFT(IF(i_id = 0, j.FillDate, BillingDate), 4 ) ,
RIGHT( IF(i_id = 0, j.FillDate, BillingDate), 3 ) ) as day,
IFNULL(ROUND(SUM(GREATEST((IF(i_id = 0 AND ISNULL(BillAmt), (PaidByPlan1+PaidByPlan2+Cashpaid), IF(ISNULL(BillAmt),(PaidByPlan1+PaidByPlan2+Cashpaid), (BillAmt+Cashpaid)))),0.00)),2),0.00) as total_pay,
Count(*) as total_transactions
FROM job j LEFT JOIN
jobtrak jt
ON j.id = jt.job_id AND
IF(i_id = 0, j.FillDate, BillingDate) BETWEEN 2014183 AND 2014212 AND
LENGTH( CONV( Jobstatus, 10, 2 ) ) NOT IN ( 5, 6, 8 ) AND
j.Active = 0
GROUP BY IF(i_id = 0, j.FillDate, BillingDate);
j.Active =0
子句中的表达式where
正在执行 nothing 。因为您有left join
,所以从job
表返回所有行,即使谓词的计算结果为false也是如此。所以,我怀疑你的意思是:
SELECT MAKEDATE( LEFT(IF(i_id = 0, j.FillDate, BillingDate), 4 ) ,
RIGHT( IF(i_id = 0, j.FillDate, BillingDate), 3 ) ) as day,
IFNULL(ROUND(SUM(GREATEST((IF(i_id = 0 AND ISNULL(BillAmt), (PaidByPlan1+PaidByPlan2+Cashpaid), IF(ISNULL(BillAmt),(PaidByPlan1+PaidByPlan2+Cashpaid), (BillAmt+Cashpaid)))),0.00)),2),0.00) as total_pay,
Count(*) as total_transactions
FROM job j LEFT JOIN
jobtrak jt
ON j.id = jt.job_id AND
IF(i_id = 0, j.FillDate, BillingDate) BETWEEN 2014183 AND 2014212 AND
LENGTH( CONV( Jobstatus, 10, 2 ) ) NOT IN ( 5, 6, 8 )
WHERE j.Active = 0
GROUP BY IF(i_id = 0, j.FillDate, BillingDate);
而JobStatus
位于jobtrak
表中。如果没有,它也应该移到where
。
真正有用的唯一索引是jobtrack(job_id)
和job(active)
。表达式LENGTH( CONV( Jobstatus, 10, 2 ) )
非常不寻常。在大多数业务应用程序中,通常不会比较十进制数的二进制表示的长度。
答案 2 :(得分:0)
查询正在检索job
表中的所有行,因为没有任何谓词限制从该表返回的行。 (引用该表的谓词出现在ON
操作的LEFT JOIN
子句中,因此这些谓词仅影响从jobtrack
表返回的行。)
就从jobtrak
表中获取行而言,该表中的每一行可能“匹配”job
表中的一行。如果job_trak.job_id
是引用job.id
的非NULL FOREIGN KEY,那将是真的。
如果要限制从job
表返回的行,则需要在WHERE
子句中包含谓词。