导航:
论坛 -> DELPHI技术
斑竹:liumazi,sephil
作者:
2019/5/31 9:50:03
标题:
请协助千万级的单表简单SQL查询优化,谢谢!
浏览:1413
加入我的收藏
楼主:
一个简单表: t_web_reportbysale 字段: f_id(整型自增),F_ReportDayfrom(时间,我用的是Char(19)),F_TotalDay(数字类型),F_ComKey (公司编码标记),真实表中还有其他接近十个字段,都是字符或者数字类型,本次查询只是针对以上字段做查询。 索引: f_id主键索引,F_ReportDayfrom索引,F_ComKey 索引 SQL语句: SELECT F_ReportDayfrom, SUM(F_TotalDay) AS SumTodayValue FROM t_web_reportbysale WHERE F_ComKey = '30010885' AND F_TotalType = '营业收入' GROUP BY F_ReportDayfrom ORDER BY F_ReportDayfrom DESC LIMIT 6; 也就是我要查询最新的6天数据,表行数接近千万行。目前查询大概需要7-8秒。 请问如何优化?
----------------------------------------------
-
作者:
2019/5/31 10:15:26
1楼:
GROUP BY F_ReportDayfrom 就慢在这里了,你这个是时间还是日期?如果是时间你这么做何意?
----------------------------------------------
-
作者:
2019/5/31 10:28:40
2楼:
SQL SERVER中不是有Execution Plan吗? 它会告诉你怎么加索引.
----------------------------------------------
-
作者:
2019/5/31 12:08:17
3楼:
最影响性能的是order by子句,这个基本没办法优化。
----------------------------------------------
--
作者:
2019/5/31 13:23:17
4楼:
复合包含索引: F_ComKey,F_TotalType,F_ReportDayfrom,F_TotalDay 如果设计再进一步,预计算好结果,直接查结果
----------------------------------------------
SQL SERVER DBA QQ:315054403 曾经的Delphier 缘在上海
作者:
clin (clin)
★☆☆☆☆
-
盒子活跃会员
2019/5/31 13:31:16
5楼:
1. F_ReportDayfrom字段是Char类型的话, 比Datetime类型要耗时。 2. 先计算现在时间,通过F_ReportDayfrom>='六天前的时间' 来检索。 我想这样快些吧
----------------------------------------------
-
作者:
2019/5/31 13:42:40
6楼:
先适当缩小结果集,通过一些大致可以用的条件,比方时间在半年内的数据。估计不会很关心历史数据。然后对结果集操作。
----------------------------------------------
-
作者:
bmsr (白忙剩人)
★☆☆☆☆
-
普通会员
2019/5/31 13:56:43
7楼:
1.既然只查最近6天的数据,为何不在where 里加上6天的条件限制. 2.F_ReportDayfrom有索引但是是字符串型,他和时间型排序是否一致由这个时间字符串格式决定,如果是YYYY-MM-DD 这种方式那么是一致,可以直接在where里使用 and (F_ReportDayfrom>'2019-05-24'),'2019-05-24' 可用时间函数today 之类的算出来(不同的数据库函数不同)再转成字符串. ORACLE 为例: and ((F_ReportDayfrom>to_char((sysdate -6), 'yyyy-mm-dd'))
----------------------------------------------
http://blog.sina.com.cn/bmsrnote
作者:
2019/5/31 15:14:41
8楼:
1.数据表里的最近6天,未必是现实中的最近6天,因为可能有些商户某一天没数据。 2.我测试了一下,对于时间是Char(19)和datetime类型影响还是极小,不至于那么慢的。 这是mysql数据表,因为有limit。 查了一下资料,感觉还是对于找最新的6天数据,因为据说是要翻到最后页,所以导致查询慢。 F_ReportDayfrom,是有重复的,所以要是SUM。 如果实在时间上做一下限制,貌似更慢,比如,在Where里加上条件 AND (F_ReportDayfrom>'2019-05-01') 效率会更差。
----------------------------------------------
-
作者:
jfhyn (贺兰之边)
★☆☆☆☆
-
普通会员
2019/5/31 15:23:50
9楼:
时间为什么不用时间类型? 主索引为什么不用时间+公司编码?
----------------------------------------------
-
作者:
2019/5/31 18:54:38
10楼:
时间不用date类型,时间比较是用字符串比较是一个比较耗时的操作,正常加了主键和索引的字段的简单检索还是很快的,但是统计分析就会慢。我曾经有个3000万记录的oracle表,简单检索还是很快的
----------------------------------------------
-
作者:
2019/5/31 20:16:27
11楼:
查了一下mysql也有分区表,改分区表吧,要不1亿条的时候咋办
----------------------------------------------
-
作者:
2019/5/31 20:33:52
12楼:
顶楼上,先用分区表对付吧。。。 如果这个查询经常用,那么最好弄个中间表出来。 还不行的话,直接堆机器吧,堆个百二八十台机器,这种查询也是秒出。。。
----------------------------------------------
弱小和无知不是生存的障碍,傲慢才是!
作者:
2019/6/1 10:32:51
13楼:
GROUP BY之后使得一切其他索引失效了 所以,你应该先where 筛选,再group by, 再order by
----------------------------------------------
-
作者:
2019/6/1 10:36:08
14楼:
简单地说,不要limit 6, 将时间范围判断写在where里
----------------------------------------------
-
作者:
2019/6/1 11:26:21
15楼:
to roadrunner :正解,一语中的,解决了这个问题,之前一般都需要7-8秒,现在0点0几秒。感谢大侠。
----------------------------------------------
-