MYSQL 怎样获取指定月份的每一天,求助

MYSQL 怎样获取指定月份的每一天,求助,第1张

问题:

仅用慢日志文件,如何快速获取分时报告?

如果有监控系统,获取分时报告(每小时慢查询的条数报告)不难,如果只有慢日志文件,就会有点费劲。

实验:

通过 pt-query-digest --timeline 功能,可以输出带时间戳的慢查询条目

用 sed 将 timeline 报告滤出

安装 termsql

使用 termsql,将报告导入,并使用 SQL 查询一条记录,以展示 termsql 的效果

可以看到 termsql 将 timeline 报告的每一行,整理成了一条数据,放在 SQLite 中。

下面就可以尽情使用 SQL 获取分时报告:

用一个复杂一点慢日志,获得如下结果:

可以轻松定位到慢查询的热点时段,也便于发现业务的周期性规律。

termsql 是一个很方便的小工具:

1 可以用于将文本导出到 SQLite 中,方便 SQL 查询。

2 它与 ps 或者 top 合用也有惊喜,比如找出 CPU 占用率高于 25% 的进程:

   在统计数据的需求中很容易出现按照天来统计数据的场景,有时某一列的维度在那天并没有产生数据,但是又没有一列是可以确保每天都是有数据的,由于mysql中并没有fulljoin这样的关联方式,在这种情况下关联查询就有些费劲,解决的办法也是多种多样,毕竟条条大路通罗马嘛,其他的就不说了,这里介绍一种相对方便的方法。

   产生一个足够长的时间列,这个列要能够包含想要统计的所有日期。这个思路的实现很泛,可以创建一个日期的临时表,然后将想要查的日期插入,抛开创建表比较麻烦之外,一般在职能比较完善的公司,生产环境创建表或者修改数据是需要交给专门的DBA去 *** 作的,各种流程。。。相对这个较简单的一种方式就是创建存储过程,然后产生时间列,这也是一种解决办法。

   我的思路是先定义一个时间变量并初始化,然后和某个数据足够多的表关联查询获取时间列,这个表一般选取某张要查的表即可,数据条数只要超过需要查询的条数即可,足够即可,太多就是浪费,降低查询效率。

   比如说我要查询2018-01-10到2018-01-20每天的数据,那么就可以写成

   其中,cdate是我定义的一个时间变量,初始化的值是2018-01-09,因为在外面那部分执行之后值已经加1了,已经不是2018-01-10了;data_t是我关联产生记录的实体表,这个表只有一个要求,就是能帮我们产生足够的时间列条数,后面的limit 15是帮助我产生15条时间记录,可以换成其他条件;生成的t0其实就是15条全为2018-01-09的记录,外面的查询在每扫描一条t0的记录就会加1天,这样就会产生连续的时间列;WHERE后面是最终查询的截止条件,换成其他的也可以。

关联其他表举例:

查询从2018-01-10到当前日期每天的统计数据

  通过上面的例子我想大部分人应该可以灵活变化了,比如查询多少天内每天的统计数据,某几个月内每月的统计数据等等,通过修改上面给的例子里面的sql完全可以做到,可以说这种思路就是个‘万能模板’,希望本文能够帮到大家。

以每24小时作为一份时间(而非自然日),根据用户的配置有两种工作模式:带状模式中,用户仅定义开始日期时,从开始日期(含)开始,每份时间1个分片地无限增加下去;环状模式中,用户定义了开始日期和结束日期时,以结束日期(含)和开始日期(含)之间的时间份数作为分片总数(分片数量固定),以类似取模的方式路由到这些分片里。

1 DBLE 启动时,读取用户在 rulexml 配置的 sBeginDate 来确定起始时间

2 读取用户在 rulexml 配置的 sPartionDay 来确定每个 MySQL 分片承载多少天内的数据

3 读取用户在 rulexml 配置的 dateFormat 来确定分片索引的日期格式

4 在 DBLE 的运行过程中,用户访问使用这个算法的表时,WHERE 子句中的分片索引值(字符串),会被提取出来尝试转换成 Java 内部的时间类型

5 然后求分片索引值与起始时间的差,除以 MySQL 分片承载的天数,确定所属分片

1 DBLE 启动时,读取用户在 rulexml 配置的起始时间 sBeginDate、终止时间 sEndDate 和每个 MySQL 分片承载多少天数据 sPartionDay

2 根据用户设置,建立起以 sBeginDate 开始,每 sPartionDay 天一个分片,直到 sEndDate 为止的一个环,把分片串联串联起来

3 读取用户在 rulexml 配置的 defaultNode

4 在 DBLE 的运行过程中,用户访问使用这个算法的表时,WHERE 子句中的分片索引值(字符串),会被提取出来尝试转换成 Java 内部的日期类型

5 然后求分片索引值与起始日期的差:如果分片索引值不早于 sBeginDate(哪怕晚于 sEndDate),就以 MySQL 分片承载的天数为模数,对分片索引值求模得到所属分片;如果分片索引值早于 sBeginDate,就会被放到 defaultNode 分片上

与MyCat的类似分片算法对比

中间件

DBLE

MyCat

分片算法种类 date 分区算法 按日期(天)分片

两种中间件的取模范围分片算法使用上无差别

开发注意点

分片索引1 必须是字符串,而且 javatextSimpleDateFormat 能基于用户指定的 dateFormat 来转换成 javautilDate

分片索引2 提供带状模式和环状模式两种模式

分片索引3 带状模式以 sBeginDate(含)起,以 86400000 毫秒(24 小时整)为一份,每 sPartionDay 份为一个分片,理论上分片数量可以无限增长,但是出现 sBeginDate 之前的数据而且没有设定 defaultNode 的话,会路由失败(如果有 defaultNode,则路由至 defaultNode)

分片索引4 环状模式以 86400000 毫秒(24 小时整)为一份,每 sPartionDay 份为一个分片,以 sBeginDate(含)到 sEndDate(含)的时间长度除以单个分片长度得到恒定的分片数量,但是出现 sBeginDate 之前的数据而且没有设定 defaultNode 的话,会路由失败(如果有 defaultNode,则路由至 defaultNode)

分片索引5 无论哪种模式,分片索引字段的格式化字符串 dateFormat 由用户指定

分片索引6 无论哪种模式,划分不是以日历时间为准,无法对应自然月和自然年,且会受闰秒问题影响

运维注意点

扩容1 带状模式中,随着 sBeginDate 之后的数据出现,分片数量的增加无需再平衡

扩容2 带状模式没有自动增添分片的能力,需要运维手工提前增加分片;如果路由策略计算出的分片并不存在时,会导致失败

扩容3 环状模式中,如果新旧 [sBeginDate,sEndDate] 之间有重叠,需要进行部分数据迁移;如果新旧 [sBeginDate,sEndDate] 之间没有重叠,需要数据再平衡

配置注意点

配置项1 在 rulexml 中,可配置项为 <propertyname="sBeginDate"> 、 <propertyname="sPartionDay"> 、 <propertyname="dateFormat"> 、 <propertyname="sEndDate"> 和 <propertyname="defaultNode">

配置项2在 rulexml 中配置 <propertyname="dateFormat">,符合 javatextSimpleDateFormat 规范的字符串,用于告知 DBLE 如何解析sBeginDate和sEndDate

配置项3在 rulexml 中配置 <propertyname="sBeginDate">,必须是符合 dateFormat 的日期字符串

配置项4在 rulexml 中配置 <propertyname="sEndDate">,必须是符合 dateFormat 的日期字符串;配置了该项使用的是环状模式,若没有配置该项则使用的是带状模式

配置项5在 rulexml 中配置 <propertyname="sPartionDay">,非负整数,该分片策略以 86400000 毫秒(24 小时整)作为一份,而 sPartionDay 告诉 DBLE 把每多少份放在同一个分片

配置项6在 rulexml 中配置 <propertyname="defaultNode"> 标签,非必须配置项,不配置该项的话,用户的分片索引值没落在 mapFile 定义

首先要考虑给数据库减压,意思就是让数据库做最简单的事情。你可以把条件在php里边组装好,然后让mysql只单一的执行查询就好了,php的时间代码给你贴一下吧

<php

date_default_timezone_set('Asia/Shanghai'); 

echo "今天:"date("Y-m-d H:i:s")"<br>";     

echo "昨天:"date("Y-m-d",strtotime("-1 day")), "<br>";     

echo "明天:"date("Y-m-d",strtotime("+1 day")) "<br>";  

echo "一周后:"date("Y-m-d",strtotime("+1 week")) "<br>"; 

echo "一周前:"date("Y-m-d",strtotime("-1 week")) "<br>";    

echo "一周零两天四小时两秒后:"date("Y-m-d G:H:s",strtotime("+1 week 2 days 4 hours 2 seconds")) "<br>";     

echo "下个星期四:"date("Y-m-d",strtotime("next Thursday")) "<br>";     

echo "上个周一:"date("Y-m-d",strtotime("last Monday"))"<br>";     

echo "一个月前:"date("Y-m-d",strtotime("last month"))"<br>";     

echo "一个月后:"date("Y-m-d",strtotime("+1 month"))"<br>";     

echo "十年后:"date("Y-m-d",strtotime("+10 year"))"<br>"; 

echo '<hr/>';

//php获取今日开始时间戳和结束时间戳 

$beginToday=mktime(0,0,0,date('m'),date('d'),date('Y'));

$endToday=mktime(0,0,0,date('m'),date('d')+1,date('Y'))-1;

echo "今日开始时间戳和结束时间戳",'开始:',$beginToday,'结束:',$endToday,'<br/>';

echo "今日开始时间:",date("Y-m-d H:i:s",$beginToday),'<br/>';

echo "今日结束时间:",date("Y-m-d H:i:s",$endToday),'<br/>';

echo '<hr/>';

//php获取昨日起始时间戳和结束时间戳

$beginYesterday=mktime(0,0,0,date('m'),date('d')-1,date('Y'));

$endYesterday=mktime(0,0,0,date('m'),date('d'),date('Y'))-1; 

echo "昨日开始时间戳和结束时间戳",'开始:',$beginYesterday,'结束:',$endYesterday,'<br/>';

echo "昨日开始时间:",date("Y-m-d H:i:s",$beginYesterday),'<br/>';

echo "昨日结束时间:",date("Y-m-d H:i:s",$endYesterday),'<br/>';

echo '<hr/>';

//php获取上周起始时间戳和结束时间戳

$beginLastweek=mktime(0,0,0,date('m'),date('d')-date('w')+1-7,date('Y'));

$endLastweek=mktime(23,59,59,date('m'),date('d')-date('w')+7-7,date('Y'));

echo "上周开始时间戳和结束时间戳",'开始:',$beginLastweek,'结束:',$endLastweek,'<br/>';

echo "上周开始时间:",date("Y-m-d H:i:s",$beginLastweek),'<br/>';

echo "上周结束时间:",date("Y-m-d H:i:s",$endLastweek),'<br/>';

echo '<hr/>';

//php获取本月起始时间戳和结束时间戳

$beginThismonth=mktime(0,0,0,date('m'),1,date('Y'));

$endThismonth=mktime(23,59,59,date('m'),date('t'),date('Y'));

echo "本月开始时间戳和结束时间戳",'开始:',$beginThismonth,'结束:',$endThismonth,'<br/>';

echo "本月开始时间:",date("Y-m-d H:i:s",$beginThismonth),'<br/>';

echo "本月结束时间:",date("Y-m-d H:i:s",$endThismonth),'<br/>';

>

语句如下:

--days 是time当月的天数

Select id,time,Days=

TIMESTAMPDIFF(day,time,(DATE_add(time,INTERVAL 1 month))) From 表

--这个方式是给原本时间加一个月和原本时间对比天数差异得来的,还有用计算出月末获取月末的Day得到

以上就是关于MYSQL 怎样获取指定月份的每一天,求助全部的内容,包括:MYSQL 怎样获取指定月份的每一天,求助、mysql按照每天/每月等统计数据(连续不间断,当天/月没有数据为0)、mysql分别获取已有数据date中的年月日等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9878743.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存