如何最小化SQL查询以非常快速地提供输出?

时间:2019-02-11 08:34:01

标签: mysql sql

我有两个查询,从中创建了一个查询,该查询为我提供了完整的数据,但是问题是执行时间很长。

我正在使用几种情况,因为它花费了很多时间,我只想知道是否可以进一步将其最小化,以免影响输出但执行得更快。

查询1

select outlet, sum(netamount) 
from syncbill 
where cancelled<>'Y' 
and year(curdate())=year(billdate) 
and month(curdate())=month(billdate) 
group by OUTLET;

Query2

select outlet,sum(netamount) 
from syncbill 
where cancelled<>'Y' 
and year(curdate())=year(billdate) 
group by OUTLET;

我正在合并以上两个查询以一次性获得结果

新查询

select  b.CUSTOMERDESCRIPTOR as outlet,
        round(sum(case when year(curdate())=year(a.billdate) and month(curdate())=month(a.billdate) then a.netamount else 0 end)) as monthAmount, 
        ROUND(SUM(CASE WHEN YEAR(CURDATE() + INTERVAL 9 MONTH) = YEAR(billdate + INTERVAL 9 MONTH) THEN netamount ELSE 0 END)) as yearAmount , 
        round(Sum(case when a.billdate >= date(now()) then a.netamount else 0 end)) as Transaction
from syncbill a Inner Join
     ecustomer b
     on a.outlet = b.CUSTOMERIDENTIFIER 
where a.cancelled <> 'Y' and
      outlet in (select CUSTOMERIDENTIFIER from mt_distributrol where mt_distributr_vcdistributrcode = 'AAAA')
group by a.OUTLET

我在上面的查询中所做的是

如果有数据,则计算当前月份数据和当前年(财务年度)数据,然后计算其他数据0

但是要花费很多时间,这似乎是非常糟糕的用户体验。如何将其最小化?

编辑

创建索引后,我进行了新查询,但是查询显示错误。这是我的查询:

select outlet,round(sum(case when year(curdate())=year(billdate) and month(curdate())=month(billdate) then netamount else 0 end)) as monthAmount, ROUND(SUM(CASE WHEN YEAR(CURDATE() + INTERVAL 9 MONTH) = YEAR(billdate + INTERVAL 9 MONTH) THEN netamount ELSE 0 END)) as yearAmount , round(Sum(case when billdate >= date(now()) then netamount else 0 end)) as Transaction from syncbill where cancelled<>'Y' and force index (ix_cancelled, ix_outlet) and force INDEX (ix_outlet) FOR group by OUTLET

这是我遇到的错误

强行查询

select  b.CUSTOMERDESCRIPTOR as outlet,round(sum(case when year(curdate())=year(a.billdate) and month(curdate())=month(a.billdate) then a.netamount else 0 end)) as monthAmount, ROUND(SUM(CASE WHEN YEAR(CURDATE() + INTERVAL 9 MONTH) = YEAR(billdate + INTERVAL 9 MONTH) THEN netamount ELSE 0 END)) as yearAmount , round(Sum(case when a.billdate >= date(now()) then a.netamount else 0 end)) as Transaction from  syncbill a force index (ix_cancelled_OUTLET_billdate) Inner Join ecustomer b on a.outlet = b.CUSTOMERIDENTIFIER where    a.cancelled<>'Y' and  outlet in(select CUSTOMERIDENTIFIER from mt_distributrol where mt_distributr_vcdistributrcode = 'AAAA')  group by   a.OUTLET

error I am getting from new query after creating indexes

final query result

after running the query with explain

table structure in database

2 个答案:

答案 0 :(得分:1)

我建议您创建几个索引: 为分组依据设置一个“出口”,另一个取消以改善过滤条件。

CREATE  INDEX ix_outlet ON syncbill(outlet);

CREATE  INDEX ix_cancelled ON syncbill(cancelled);

然后强制mysql使用那些

select a,b,c
from my_table
force index (ix_cancelled, ix_outlet)
force INDEX (ix_outlet) FOR GROUP BY
where a = condition_1
group by a,b

答案 1 :(得分:1)

为了提高new_Query的性能,您应该按照我编写的顺序在三个Columns(取消的,OUTLET)上有一个索引;因为在查询执行中,首先执行表达式,然后按表达式分组,最后选择语句;如果索引数据页是使用按此顺序使用的列创建的,则数据查找的速度会提高。

CREATE  INDEX ix_cancelled_OUTLET ON syncbill(cancelled, OUTLET);