本来你的语句很漂亮,用不着优化。如果你实在很关心性能,可以在WHERE部分限制一下【净入库.`入库日期`】的时间范围在1~9月,避免全表浏览,如果该字段有索引,可以快一点点。
AND 净入库.`入库日期` BETWEEN '2016-01-01 00:00:00.0' AND '2016-09-30 00:00:00.0'
SELECTzc.纳税人名称,
sum(CASE
WHEN 净入库.`征收项目` = '城镇土地使用税' THEN
净入库.实缴金额
ELSE
0
END) 土地使用税,
sum(CASE
WHEN 净入库.`征收项目` = '房产税' THEN
净入库.实缴金额
ELSE
0
END) 房产税
FROM
清册 zc,
净入库
WHERE
zc.`登记序号` =净入库.登记序号
AND 净入库.`入库日期` BETWEEN '2016-01-01 00:00:00.0' AND '2016-09-30 00:00:00.0'
group by zc.`登记序号`
CREATE?TABLE?`a`?(`id`?mediumint(8)?unsigned?NOT?NULL?AUTO_INCREMENT,`fid`?smallint(6)?unsigned?NOT?NULL?DEFAULT?'0',`cnt`?smallint(6)?unsigned?NOT?NULL?DEFAULT?'0',...
...
...
PRIMARY?KEY?(`id`),
KEY?`idx_fid`?(`fid`),
)?ENGINE=MyISAM?DEFAULT?CHARSET=utf8
表b
CREATE?TABLE?`b`?
(`fid`?smallint(6)?unsigned?NOT?NULL?AUTO_INCREMENT,`name`?char(50)?NOT?NULL?DEFAULT?'',
...
...
...
PRIMARY?KEY?(`fid`),
)?ENGINE=MyISAM?DEFAULT?CHARSET=utf8
*** 作SQL如下:
SELECT?COUNT(*)?AS?num1,?SUM(a.cnt)+COUNT(*)?AS?num2FROM?a,?b
WHERE?b.fid='10913'?AND?a.fid=b.fid
我们先看下执行计划:
我们可以看到扫描行数是229049行,执行时间:
太可怕了,运行set profiling=1,让我们看看时间主要消耗在哪里?
sending data花费的时间较长,那这段时间到底是做什么的呢?先看下这个吧:http://renxijun.blog.sohu.com/82906360.html意思是它在为select语句准备数据,解决办法:
建索引:
create index idx_fid_cnt on a (fid,cnt)
再看下,执行计划和执行时间:
总结:使用恰当的索引,是sql的效率倍增,类似sum的函数还有min(),max(),这些都需要在字段上建索引。
mysql的执行顺序是这样的,你想想,不知道有没有什么好的方法1、from子句组装来自不同数据源的数据;2、where子句基于指定的条件对记录行进行筛选;3、group by子句将数据划分为多个分组;4、使用聚集函数进行计算;5、使用having子句筛选分组;6、计算所有的表达式;7、使用order by对结果集进行排序。貌似 uid建索引应该是比较快的欢迎分享,转载请注明来源:内存溢出
评论列表(0条)