iposdb数据库 date函数优化

如下4条SQL,明显是2类SQL语句。2017年5月19号

问题:走了两次全表。
select count(*) 活跃商户数量  from (select merchant_code,COUNT(DISTINCT concat(merchant_code,DATE(create_date))) merchantCodeCreateDate from pos_order where DATE(create_date)>=‘2017-05-12‘ and DATE(create_date)<=‘2017-05-18‘ and trade_status=‘2‘ GROUP BY merchant_code HAVING merchantCodeCreateDate>=4) as tmptable;

select count(*) 活跃机具数量 from (select machine_sn,COUNT(DISTINCT concat(machine_sn,DATE(create_date))) machineSnCreateDate from pos_order where DATE(create_date)>=‘2017-05-12‘ and DATE(create_date)<=‘2017-05-18‘ and trade_status=‘2‘ GROUP BY merchant_code HAVING machineSnCreateDate>=4) as tmptable;

问题:走了一次全表扫描
select count(DISTINCT merchant_code) 交易商户数量 from pos_order where DATE(create_date)>=‘2017-05-12‘ and DATE(create_date)<=‘2017-05-18‘ and trade_status=‘2‘;

select count(DISTINCT machine_sn) 交易机具数量 from pos_order where DATE(create_date)>=‘2017-05-12‘ and DATE(create_date)<=‘2017-05-18‘ and trade_status=‘2‘;

发现:
1 4个查询都是pos_order 的查询。
2 不必要的自身连接
3 count(辅助索引)快于count(*)
4 count(distinct)优化                --算了,这点没必要了。
例子:
select count(DISTINCT machine_sn) 交易机具数量 from pos_order where DATE(create_date)>=‘2017-05-12‘ and DATE(create_date)<=‘2017-05-18‘ and trade_status=‘2‘;
改写:
explain select count(machine_sn)  交易机具数量  from pos_order where machine_sn=any(select distinct machine_sn from pos_order)  and DATE(create_date)>=‘2017-05-12‘ and DATE(create_date)<=‘2017-05-18‘ and trade_status=‘2‘;

any关键字,只要满足内层查询语句返回一个结果中的任何一个,就可以通过条件来执行外层查询语句。
all与any相反,只有满足内层查询语句返回的所有结果,才可以执行外层查询语句。
explain select count(machine_sn)  交易机具数量  from pos_order where machine_sn=all(select distinct machine_sn from pos_order);
machine_sn           | varchar(32)  | NO   | MUL | NULL       ‘机器KSN号‘

第二种语法改写:
select count(DISTINCT machine_sn) 交易机具数量 from pos_order where DATE(create_date)>=‘2017-05-12‘ and DATE(create_date)<=‘2017-05-18‘ and trade_status=‘2‘;

强制走索引,但是有判断 还是全表。使用union all方式。
explain select count(DISTINCT machine_sn) 交易机具数量 from pos_order union all select count(machine_sn) from pos_order force index(idx_create_date) where DATE(create_date)>=‘2017-05-12‘ and DATE(create_date)<=‘2017-05-18‘ and trade_status=‘2‘;

改写函数名称
select count(DISTINCT machine_sn) 交易机具数量 from pos_order where create_date BETWEEN DATE_SUB(curdate(),INTERVAL 1 day) AND date_sub(curdate(),INTERVAL 7 day)  and trade_status=‘2‘;

很纳闷啊 ,怎么会没数。
业务SQL语句:
mysql> select count(DISTINCT merchant_code) 交易商户数量 from pos_order where DATE(create_date)>=‘2017-05-12‘ and DATE(create_date)<=‘2017-05-18‘ and trade_status=‘2‘;
+--------------------+
| 交易商户数量       |
+--------------------+
|              39882 |
+--------------------+
1 row in set (1 min 48.89 sec)

mysql> select date_sub(curdate(),INTERVAL 7 day),DATE_SUB(curdate(),INTERVAL 1 day);      
+------------------------------------+------------------------------------+
| date_sub(curdate(),INTERVAL 7 day) | DATE_SUB(curdate(),INTERVAL 1 day) |
+------------------------------------+------------------------------------+
| 2017-05-12                         | 2017-05-18                         |
+------------------------------------+------------------------------------+
1 row in set (0.00 sec)

大的放前面。
mysql> select count(DISTINCT machine_sn) 交易机具数量 from pos_order where create_date >= DATE_SUB(curdate(),INTERVAL 1 day) AND create_date <= date_sub(curdate(),INTERVAL 7 day)  and trade_status=‘2‘;          
+--------------------+
| 交易机具数量       |
+--------------------+
|                  0 |
+--------------------+
1 row in set (0.00 sec)

数值对不上,也是没谁了。

去掉函数。从ALL变成了range     但是数据 没有等价。
select count(DISTINCT merchant_code) 交易商户数量 from pos_order where create_date>=‘2017-05-12 00:00:00‘ and create_date<=‘2017-05-18 23:59:59‘  and trade_status=‘2‘;

select count(DISTINCT merchant_code) 交易商户数量 from pos_order force index(idx_create_date) where create_date>=‘2017-05-12 00:00:00‘ and create_date<=‘2017-05-18 23:59:59‘  and trade_status=‘2‘;

优化distinct最有效的方法是利用索引来做排重操作,先把排重的记录查找出来在通过count统计,这样效果更高
表量级:14745537      1474W条+数据。
目前:pos_order 表的索引情况如下:
知识点哈:如果时间类型 create_date 用来做运算的话 是不走索引的 (故idx_create_date索引无效)

表结构:  还算优秀  存在自增id主键。

时间: 2024-10-06 13:50:35

iposdb数据库 date函数优化的相关文章

数据库访问性能优化

特别说明: 1.  本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识: 2.  本文许多示例及概念是基于Oracle数据库描述,对于其它关系型数据库也可以参考,但许多观点不适合于KV数据库或内存数据库或者是基于SSD技术的数据库: 3.  本文未深入数据库优化中最核心的执行计划分析技术. 读者对像: 开发人员:如果你是做数据库开发,那本文的内容非常适合,因为本文是从程序员的角度来谈数据库性能优化. 架构师:如果你已经是数据库应用的架构师,那本文的

数据库访问性能优化 Oracle

特别说明: 1.  本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识: 2.  本文许多示例及概念是基于Oracle数据库描述,对于其它关系型数据库也可以参考,但许多观点不适合于KV数据库或内存数据库或者是基于SSD技术的数据库: 3.  本文未深入数据库优化中最核心的执行计划分析技术. 读者对像: 开发人员:如果你是做数据库开发,那本文的内容非常适合,因为本文是从程序员的角度来谈数据库性能优化. 架构师:如果你已经是数据库应用的架构师,那本文的

[转]面向程序员的数据库访问性能优化法则

原文地址:http://blog.csdn.net/yzsind/article/details/6059209 特别说明: 1.  本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识: 2.  本文许多示例及概念是基于Oracle数据库描述,对于其它关系型数据库也可以参考,但许多观点不适合于KV数据库或内存数据库或者是基于SSD技术的数据库: 3.  本文未深入数据库优化中最核心的执行计划分析技术. 读者对像: 开发人员:如果你是做数据库开发,那

Oracle学习总结(8)—— 面向程序员的数据库访问性能优化法则

特别说明: 1.  本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识: 2.  本文许多示例及概念是基于Oracle数据库描述,对于其它关系型数据库也可以参考,但许多观点不适合于KV数据库或内存数据库或者是基于SSD技术的数据库: 3.  本文未深入数据库优化中最核心的执行计划分析技术. 读者对像: 开发人员:如果你是做数据库开发,那本文的内容非常适合,因为本文是从程序员的角度来谈数据库性能优化. 架构师:如果你已经是数据库应用的架构师,那本文的

面向程序员的数据库访问性能优化法则

此文于2010-12-08被推荐到CSDN首页 如何被推荐? 面向程序员的数据库访问性能优化法则 特别说明: 1.  本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识: 2.  本文许多示例及概念是基于Oracle数据库描述,对于其它关系型数据库也可以参考,但许多观点不适合于KV数据库或内存数据库或者是基于SSD技术的数据库: 3.  本文未深入数据库优化中最核心的执行计划分析技术. 读者对像: 开发人员:如果你是做数据库开发,那本文的内容非常适

SQL Date 函数

SQL 日期 当我们处理日期时,最难的任务恐怕是确保所插入的日期的格式,与数据库中日期列的格式相匹配. 只要数据包含的只是日期部分,运行查询就不会出问题.但是,如果涉及时间,情况就有点复杂了. 在讨论日期查询的复杂性之前,我们先来看看最重要的内建日期处理函数. MySQL Date 函数 下面的表格列出了 MySQL 中最重要的内建日期函数: 函数 描述 NOW() 返回当前的日期和时间 CURDATE() 返回当前的日期 CURTIME() 返回当前的时间 DATE() 提取日期或日期/时间表

对.net orm工具Dapper在多数据库方面的优化

Dapper是近2年异军突起的新ORM工具,它有ado.net般的高性能又有反射映射实体的灵活性,非常适合喜欢原生sql的程序员使用,而且它源码很小,十分轻便.我写本博客的目的不是为了介绍Dapper,而是要将我使用Dapper迁移数据库过程中遇到的bug和一些优化介绍给大家,Dapper在多数据库支持上有些问题,我做了以下5个方面的优化. 一:Dapper核心库存在一个重要的bug是各数据库默认返回类型不同造成的,像count,sum等一些函数在不同的数据库返回类型不同.比如 select c

【心得】怪异的JS的Date函数

我们知道new Date('2013/1/1')是2013年1月1日, 那么new Date('2013/1/366')会报无效日期格式吗?答案是,这是一个有效的日期,但是他是表示2014年1月1日. 相当于2013/1/1+365d. 那么new Date('2012/1/367')是2013年1月1日,我想说的是,内部已经处理闰年的情况了. 会有什么问题?假设我们把'2013/1/366'传到数据库,用数据库的Convert(datetime,'2013/1/366')转换时会这样: 从 c

SQL高级应用(Date函数)

SQL 日期 当我们处理日期时,最难的任务恐怕是确保所插入的日期的格式,与数据库中日期列的格式相匹配. 只要数据包含的只是日期部分,运行查询就不会出问题.但是,如果涉及时间,情况就有点复杂了. 在讨论日期查询的复杂性之前,我们先来看看最重要的内建日期处理函数. MySQL Date 函数 下面的表格列出了 MySQL 中最重要的内建日期函数: 函数 描述 NOW() 返回当前的日期和时间 CURDATE() 返回当前的日期 CURTIME() 返回当前的时间 DATE() 提取日期或日期/时间表