MySQL 走错索引导致驱动表选错

原sql:

select count(*) from mpay_order mpayOrder inner join mrecharge_order_info orderinfo on mpayOrder.order_num = orderinfo.order_num inner join mpay_trade mpayTrade on mpayOrder.order_num = mpayTrade.order_num where TRUE and left(mpayTrade.trade_num,2) = ‘10‘ and TIMESTAMPDIFF(SECOND,mpayOrder.create_time,‘2014-12-19 00:00:00‘) <= 0 and TIMESTAMPDIFF(SECOND,mpayOrder.create_time,‘2014-12-19 12:40:32‘) >= 0;

执行计划:

+----+-------------+-----------+-------+---------------+---------------+---------+--------------------------+--------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
+----+-------------+-----------+-------+---------------+---------------+---------+--------------------------+--------+-------------+ 
| 1 | SIMPLE | orderinfo | index | order_num_idx | order_num_idx | 93 | NULL | 184192 | Using index | 
| 1 | SIMPLE | mpayTrade | ref | order_num_idx | order_num_idx | 93 | mpay.orderinfo.order_num | 1 | Using where | 
| 1 | SIMPLE | mpayOrder | ref | order_num_idx | order_num_idx | 93 | mpay.mpayTrade.order_num | 1 | Using where | 
+----+-------------+-----------+-------+---------------+---------------+---------+--------------------------+--------+-------------+

执行时间:1 row in set (2.69 sec)

===>建议优化为,改成成如下:

select count(*) from mpay_order mpayOrder inner join mrecharge_order_info orderinfo on mpayOrder.order_num = orderinfo.order_num inner join mpay_trade mpayTrade on mpayOrder.order_num = mpayTrade.order_num where TRUE and left(mpayTrade.trade_num,2) = ‘10‘ and mpayOrder.create_time>=‘2014-12-19 00:00:00‘ and mpayOrder.create_time<=‘2014-12-19 12:40:32‘;

执行计划:

+----+-------------+-----------+-------+-------------------------------+-----------------+---------+--------------------------+------+--------------------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
+----+-------------+-----------+-------+-------------------------------+-----------------+---------+--------------------------+------+--------------------------+ 
| 1 | SIMPLE | mpayOrder | range | order_num_idx,create_time_idx | create_time_idx | 9 | NULL | 1484 | Using where | 
| 1 | SIMPLE | orderinfo | ref | order_num_idx | order_num_idx | 93 | mpay.mpayOrder.order_num | 1 | Using where; Using index | 
| 1 | SIMPLE | mpayTrade | ref | order_num_idx | order_num_idx | 93 | mpay.mpayOrder.order_num | 1 | Using where | 
+----+-------------+-----------+-------+-------------------------------+-----------------+---------+--------------------------+------+--------------------------+

执行时间:1 row in set (0.03 sec)

优化思路:去掉函数TIMESTAMPDIFF,建立索引alter table mpay_order add index `create_time_idx`(create_time);

通过对mpay_order加索引后,优化器选择小的驱动表mpayOrder 1484 ,减少Nest Loop的代价。

索引已经添加,需要改写sql。

时间: 2024-10-11 15:53:50

MySQL 走错索引导致驱动表选错的相关文章

mysql中的索引原理与表设计

索引是有效使用数据库的基础,但你的数据量很小的时候,或许通过扫描整表来存取数据的性能还能接受,但当数据量极大时,当访问量极大时,就一定需要通过索引的辅助才能有效地存取数据.一般索引建立的好坏是性能好坏的成功关键. 1.InnoDb数据与索引存储细节 使用InnoDb作为数据引擎的Mysql和有聚集索引的SqlServer的数据存储结构有点类似,虽然在物理层面,他们都存储在Page上,但在逻辑上面,我们可以把数据分为三块:数据区域,索引区域,主键区域,他们通过主键的值作为关联,配合工作.默认配置下

MySQL学习笔记02_数据库和表的基本操作

02_1 操作数据库 (1)创建数据库 CREATE DATABASE [IF NOT EXISTS] db_name [create_specification[, create_specification]...] 解释: [IF NOT EXISTS]创建时提前检查一下是否存在数据库 create_specification:(创建条件) [DEFAULT] CHARACTER SET charset_name | [DEFAULT] COLLATE collation_name CHAR

mysql为什么有些时候会选错索引

1.基本概念 在MySQL中一张表其实是可以支持多个索引的.但是,你写SQL语句的时候,并没有主动指定使用哪个索引.也就是说,使用哪个索引是由MySQL来确定的. 一般在数据库使用的时候回遇到这样的问题,一条本来可以执行很快的语句,却由于MySQL选错了索引,导致执行速度变得很慢. 举例说明: 我们先建一个简单的表,表里有a.b两个字段,并分别建上索引: CREATE TABLE `t` ( `id` int(11) NOT NULL, `a` int(11) DEFAULT NULL, `b`

mysql选错娱乐平台源码搭建索引的原因与处理

mysql选错娱乐平台源码搭建<企娥21717 93408>索引的原因与处理1执行计划预估行数错误2order by和主键类型不同导致 索引基数一个索引上不同的值越多,这个索引的区分度就越好.而一个索引上不同的值的个数,我们称之为"基数"(cardinality).也就是说,这个基数越大,索引的区分度越好.我们可以使用 show index方法,看到一个索引的基数.MySQL 是怎样得到索引的基数的呢?  这里,我给你简单介绍一下 MySQL 采样统计的方法.为什么要采样统

MySQL之 index merge 走错索引案例

条件:MySQL 版本:percona server 5.5.18 sql优化案例一: [email protected] 5.5.18-log cayenne 11:30:37>desc select id, grant_credit_task_id, product_id, product_code, user_id, member_id, user_credit_money, product_credit_money, real_product_credit_money, credit_s

MYSQL数据库表排序规则不一致导致联表查询,索引不起作用问题

Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题 表更描述: 将mysql数据库中的worktask表添加ishaspic字段. 具体操作:(1)数据库worktask表新添是否有图片字段ishaspic:新添字段时,报错 [SQL] alter table WorkTask add ishaspic int(10) Null;[Err] 1034 - Incorrect key file for table 'WorkTask'; try to repair it 解决方案:新建

10 | MySQL为什么有时候会选错索引?

如果使用索引 a,每次从索引 a 上拿到一个值,都要回到主键索引上查出整行数据,这个代价优化器也要算进去的. 而如果选择扫描 10 万行,是直接在主键索引上扫描的,没有额外的代价. 优化器会估算这两个选择的代价,从结果看来,优化器认为直接扫描主键索引更快. 当然,从执行时间看来,这个选择并不是最优的. 不过需要注意的是,文章中给出的几个选错索引的例子都没有浮现出来. 原文地址:https://www.cnblogs.com/lakeslove/p/12246312.html

Mysql InnoDB 数据更新导致锁表

一.数据表结构 CREATE TABLE `jx_attach` ( `attach_id` int(11) NOT NULL AUTO_INCREMENT, `feed_id` int(11) DEFAULT NULL , `attach_name` varchar(255) NOT NULL, `cycore_file_id` varchar(255) DEFAULT NULL , `attach_size` bigint(20) NOT NULL DEFAULT '0', `complet

MySQL外键及级联删除 &amp;&amp; 表的存储引擎与创建索引 &amp;&amp; 删除数据库和表

Messages表: mysql>create table Messages( ->message_id int auto_increment primary key, ->user_name varchar(50) not null, ->author_id int not null, ->body text, ->forum_id int not null); Forums表: mysql>create table Forums( ->forum_id