DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: jeff1314
今日帖子: 10
在线用户: 3
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
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秒。
请问如何优化?
----------------------------------------------
-
作者:
男 cgzcgb (cgzcgb) ★☆☆☆☆ -
普通会员
2019/5/31 10:15:26
1楼: GROUP BY
  F_ReportDayfrom
就慢在这里了,你这个是时间还是日期?如果是时间你这么做何意?
----------------------------------------------
-
作者:
男 he_19_79 (he) ▲▲▲▲▲ -
普通会员
2019/5/31 10:28:40
2楼: SQL SERVER中不是有Execution Plan吗? 它会告诉你怎么加索引.
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2019/5/31 12:08:17
3楼: 最影响性能的是order by子句,这个基本没办法优化。
----------------------------------------------
--
作者:
男 luckyrandom (luckyrandom) ★☆☆☆☆ -
普通会员
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>='六天前的时间' 来检索。  
  我想这样快些吧
----------------------------------------------
-
作者:
男 wk_knife (wk_knife) ★☆☆☆☆ -
盒子活跃会员
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
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
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楼: 时间为什么不用时间类型?
主索引为什么不用时间+公司编码?
----------------------------------------------
-
作者:
男 wk_knife (wk_knife) ★☆☆☆☆ -
盒子活跃会员
2019/5/31 18:54:38
10楼: 时间不用date类型,时间比较是用字符串比较是一个比较耗时的操作,正常加了主键和索引的字段的简单检索还是很快的,但是统计分析就会慢。我曾经有个3000万记录的oracle表,简单检索还是很快的
----------------------------------------------
-
作者:
男 wk_knife (wk_knife) ★☆☆☆☆ -
盒子活跃会员
2019/5/31 20:16:27
11楼: 查了一下mysql也有分区表,改分区表吧,要不1亿条的时候咋办
----------------------------------------------
-
作者:
男 yayongm (昵  称) ★☆☆☆☆ -
盒子活跃会员
2019/5/31 20:33:52
12楼: 顶楼上,先用分区表对付吧。。。
如果这个查询经常用,那么最好弄个中间表出来。
还不行的话,直接堆机器吧,堆个百二八十台机器,这种查询也是秒出。。。
----------------------------------------------
弱小和无知不是生存的障碍,傲慢才是!
作者:
男 roadrunner (roadrunner) ★☆☆☆☆ -
盒子活跃会员
2019/6/1 10:32:51
13楼: GROUP BY之后使得一切其他索引失效了
所以,你应该先where 筛选,再group by, 再order by
----------------------------------------------
-
作者:
男 roadrunner (roadrunner) ★☆☆☆☆ -
盒子活跃会员
2019/6/1 10:36:08
14楼: 简单地说,不要limit 6, 将时间范围判断写在where里
----------------------------------------------
-
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
2019/6/1 11:26:21
15楼: to roadrunner :正解,一语中的,解决了这个问题,之前一般都需要7-8秒,现在0点0几秒。感谢大侠。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行66.40625毫秒 RSS