Php 执行查询需要很多时间

Php 执行查询需要很多时间,php,mysql,Php,Mysql,我有一个查询,执行这个查询需要3分钟以上的时间。我还发布了解释计划。我应该做些什么来减少执行时间?是否因为左连接需要更多的时间 SELECT d.name as doc, SUM( CASE WHEN bill_type = 'registration' AND bop.particulars = 'Consultation Fee' THEN bop.amount ELSE 0 END) AS 'op', SUM(

我有一个查询,执行这个查询需要3分钟以上的时间。我还发布了解释计划。我应该做些什么来减少执行时间?是否因为左连接需要更多的时间

SELECT d.name as doc, SUM(
        CASE 
        WHEN bill_type = 'registration' AND bop.particulars = 'Consultation Fee' THEN bop.amount
        ELSE 0
    END) AS 'op',


    SUM(
        CASE 
        WHEN bill_type = 'casuality' THEN b.payable_amount
        ELSE 0
    END) AS 'cas' ,

    SUM(
        CASE 
        WHEN bill_type = 'pharmacy' THEN b.payable_amount
        ELSE 0
    END) AS 'ph', 

    SUM(
        CASE 
        WHEN bill_type = 'lab' THEN b.payable_amount
        ELSE 0
    END) AS 'lab' ,
    SUM(
        CASE 
        WHEN bill_type = 'xray' THEN b.payable_amount
        ELSE 0
    END) AS 'x' ,
    SUM(
        CASE 
        WHEN bill_type = 'audiology' THEN b.payable_amount
        ELSE 0
    END) AS 'au',
    SUM(
        CASE 
        WHEN bill_type = 'discharge' THEN b.payable_amount + IFNULL(w.balance, 0)
        ELSE 0
    END) AS 'ip'


    FROM bills b 

    LEFT JOIN patient_wallet w on w.id =  (SELECT x.id FROM patient_wallet x WHERE x.ip_id = b.ip_id ORDER BY x.created_at DESC  LIMIT 1)
    LEFT JOIN bill_contents_op bop on bop.bill_id = b.id
    LEFT JOIN doctors d on d.id = b.doctor_id
    WHERE b.doctor_id IN(41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80) AND CAST(b.created_at AS DATE) >= '2016-06-01' AND CAST(b.created_at AS DATE) <= '2016-06-30' AND b.is_cancelled = 0 AND b.is_deleted = 0 GROUP BY d.name

当您选择*时,它运行得快吗?是。只花了14秒(显示第0-24行(总共8633行,查询花费了14.0198秒)。因此,您应该检查MySQL服务器配置。此外,您还应该检查where子句中列的索引,如果它们没有索引并且包含大量数据,则where子句将非常昂贵。您缺少一些索引:
bill\u contents\u op(bill\u id)
患者钱包x(ip\u id)
账单(医生id)
在创建的
应该是一个
日期时间
-列,而不是
varchar
(或任何内容)。您的
左联接
患者钱包
效率低下,但由于此表很小,优化它可能不会产生太大影响。您是否可以对该联接(以及您的上一个总和)进行注释,以查看它是否会改变执行(或者代码是否可以保持不变)不,时间戳很好,我只是想,因为您将列强制转换为日期。然后您可以添加一个更好的索引:
bills(doctor\u id,created\u at)
,并替换
和强制转换(b.created\u at AS date)='2016-06-01'和强制转换(b.created\u at AS date)当您选择*,它运行得快吗?是的。只花了14秒(显示第0-24行(总共8633行,查询耗时14.0198秒)。因此,您应该检查MySQL服务器配置。此外,您还应该检查where子句中列的索引,如果它们没有索引并且包含大量数据,则where子句的成本将很高。您缺少一些索引:
bill\u contents\u op(bill\u id)
患者钱包x(ip\u id)
账单(医生id)
创建的
应该是一个
日期时间
-列,而不是
varchar
(或任何内容)。您的
左联接
患者钱包
效率低下,但由于此表很小,优化它可能不会产生太大影响。您是否可以对该联接(以及您的上一个总和)进行注释,以查看它是否会改变执行(或者代码是否可以保持不变)不,时间戳很好,我只是想,因为您将列强制转换为日期。然后您可以添加一个更好的索引:
账单(医生id,创建时间)
,并替换
和强制转换(b.创建时间)>='2016-06-01'和强制转换(b.创建时间)
1
PRIMARY
b
NULL
ALL
NULL
NULL
NULL
NULL
161351
0.50
Using where; Using temporary; Using filesort
1
PRIMARY
w
NULL
eq_ref
PRIMARY
PRIMARY
4
func
1
100.00
Using where
1
PRIMARY
bop
NULL
ALL
NULL
NULL
NULL
NULL
124490
100.00
Using where; Using join buffer (Block Nested Loop)
1
PRIMARY
d
NULL
eq_ref
PRIMARY
PRIMARY
4
santhwana.b.doctor_id
1
100.00
NULL
2
DEPENDENT SUBQUERY
x
NULL
ALL
NULL
NULL
NULL
NULL
78
10.00
Using where; Using filesort