前言

mysql的sql优化器比较弱,选择执行计划貌似很随机.

案例

一、表结构说明
mysql> show create table table_order\G
*************************** 1. row ***************************
       Table: table_order
Create Table: CREATE TABLE `table_order` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `order_no` varchar(255) NOT NULL DEFAULT '',
  `shopid` int(10) unsigned NOT NULL DEFAULT '0',
  `app_id` int(10) unsigned NOT NULL DEFAULT '0',
  `activity_id` int(10) unsigned NOT NULL DEFAULT '0',
  .......

UNIQUE KEY `uk_app_no` (`shopid`,`order_no`),
  KEY `mobile_uid` (`customer_mobile`,`uid`),
  KEY `app_id` (`app_id`),
  KEY `status_expiretime` (`is_online`,`status`,`expire_time`),
  KEY `uid_spno` (`uid`,`shopid`),
  KEY `status_paytime` (`status`,`pay_time`),
  KEY `retm` (`retm`)
) ENGINE=InnoDB AUTO_INCREMENT=31583626 DEFAULT CHARSET=utf8 COMMENT='轻支付动态订单表'
1 row in set (0.01 sec)

二、案例: sql结构相同,参数不同,sql出的数据行数差距大,执行计划相同,执行效率差别很大

SQL1: 数据量:1条,  执行时间:49.27 sec

SELECT * FROM `table_order` WHERE business_status=100 AND `shopid` IN (102686, 129621) AND `status` IN (1, 18, 19) AND `retm` >= 1456675200 AND `retm` < 1456761600 ORDER BY `id` DESC LIMIT 0, 10
+----+-------------+----------------+-------+------------------------------------+---------+---------+------+------+-------------+
| id | select_type | table          | type  | possible_keys                      | key     | key_len | ref  | rows | Extra       |
+----+-------------+----------------+-------+------------------------------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | table_order | index | uk_app_no,status_paytime,retm         | PRIMARY | 4       | NULL | 2355 | Using where |
+----+-------------+----------------+-------+------------------------------------+---------+---------+------+------+-------------+

SQL2: 数据量:10000+条,  执行时间:0.27 sec

SELECT * FROM `table_order`  WHERE business_status=100 AND `shopid` IN (84010, 129621) AND `status` IN (1, 18, 19) AND `retm` >= 1456675200 AND `retm` < 1456761600 ORDER BY `id` DESC LIMIT 0, 10
+----+-------------+----------------+-------+------------------------------------+---------+---------+------+------+-------------+
| id | select_type | table          | type  | possible_keys                      | key     | key_len | ref  | rows | Extra       |
+----+-------------+----------------+-------+------------------------------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | table_order | index | uk_app_no,status_paytime,retm         | PRIMARY | 4       | NULL | 1087 | Using where |
+----+-------------+----------------+-------+------------------------------------+---------+---------+------+------+-------------+

SQL3: 数据量:10000+条,  执行时间:0.21 sec

SELECT * FROM `table_order`  WHERE business_status=100 AND `shopid` IN (84010, 129621) AND `status` IN (1, 18, 19) AND `retm` >= 1456675200 AND `retm` < 1456761600 ORDER BY `id` DESC LIMIT 1000, 10
+----+-------------+----------------+-------+------------------------------------+-----------+---------+------+-------+-----------------------------+
| id | select_type | table          | type  | possible_keys                      | key       | key_len | ref  | rows  | Extra                       |
+----+-------------+----------------+-------+------------------------------------+-----------+---------+------+-------+-----------------------------+
|  1 | SIMPLE      | table_order | range | uk_app_no,status_paytime,retm         | retm | 4       | NULL | 82208 | Using where; Using filesort |
+----+-------------+----------------+-------+------------------------------------+-----------+---------+------+-------+-----------------------------+

结果分析:
    1、sql1,按照主键索引,主键索引已经排序,查找数据,数据量不到10条,会沿着主键索引按顺序查下去,直到查完符合条件的数据,这种查法,导致类似全表查询
    2、sql2,按照主键索引,主键索引已经排序,查找数据,查到第10条,直接返回,所以查询效率高。
       同时,随着limit a,b 翻页,a的值越大,sql2 会调整查询计划,选择合适的查询计划。如SQL3

解决方案:
    可以遵循一条优化原则: "尽量早过滤", 多个索引的情况下,选择索引过滤数据量最少的。 例如sql中, where 条件A AND 条件B;如果
        where 条件A 取出的数据 < where 条件B 取出的数据,
    可以force INDEX(A)

mysql的sql优化案例的更多相关文章

  1. 基于MySQL 的 SQL 优化总结

    文章首发于我的个人博客,欢迎访问.https://blog.itzhouq.cn/mysql1 基于MySQL 的 SQL 优化总结 在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务.例行 ...

  2. 我的mysql数据库sql优化原则

    原文 我的mysql数据库sql优化原则 一.前提 这里的原则 只是针对mysql数据库,其他的数据库 某些是殊途同归,某些还是存在差异.我总结的也是mysql普遍的规则,对于某些特殊情况得特殊对待. ...

  3. MySQL之SQL优化详解(二)

    目录 MySQL之SQL优化详解(二) 1. SQL的执行顺序 1.1 手写顺序 1.2 机读顺序 2. 七种join 3. 索引 3.1 索引初探 3.2 索引分类 3.3 建与不建 4. 性能分析 ...

  4. 【MySQL】SQL优化系列之 in与range 查询

    首先我们来说下in()这种方式的查询 在<高性能MySQL>里面提及用in这种方式可以有效的替代一定的range查询,提升查询效率,因为在一条索引里面,range字段后面的部分是不生效的. ...

  5. BATJ解决千万级别数据之MySQL 的 SQL 优化大总结

    引用 在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务.例行 SQL 优化,不仅可以提高程序性能,还能减低线上故障的概率. 目前常用的 SQL 优化方式包括但不限于:业务层优化.SQL 逻 ...

  6. SQL优化案例—— RowNumber分页

    将业务语句翻译成SQL语句不仅是一门技术,还是一门艺术. 下面拿我们程序开发工程师最常用的ROW_NUMBER()分页作为一个典型案例来说明. 先来看看我们最常见的分页的样子: WITH CTE AS ...

  7. SQL 优化案例 1

    create or replace procedure SP_GET_NEWEST_CAPTCHA( v_ACCOUNT_ID in VARCHAR2, --接收短信的手机号 v_Tail_num i ...

  8. mysql索引sql优化方法、步骤和经验

    MySQL索引原理及慢查询优化 http://blog.jobbole.com/86594/ 细说mysql索引 https://www.cnblogs.com/chenshishuo/p/50300 ...

  9. (1.10)SQL优化——mysql 常见SQL优化

    (1.10)常用SQL优化 insert优化.order by 优化 1.insert 优化 2.order by 优化 [2.1]mysql排序方式: (1)索引扫描排序:通过有序索引扫描直接返回有 ...

随机推荐

  1. python 解析 配置文件

    资料: https://docs.python.org/3/library/configparser.html 环境 python 3.4.4 RawConfigParser方式 example.cf ...

  2. A - Til the Cows Come Home

    裸的最短路,试一下刚看的spfa,虽然没有看代码,不过明白了大致的思想,先写一下试试吧,而且是个稀疏图,应该会很快吧. SPFA 算法采用图的存储结构是邻接表,方法是动态优化逼近法.算法中设立了一个先 ...

  3. codeforces 610B

    Description Vika has n jars with paints of distinct colors. All the jars are numbered from 1 to n an ...

  4. 转载:Ununtu下中文乱码解决方案

    转载: 添加中文字符编码: $sudo vim /var/lib/locales/supported.d/local #添加下面的中文字符集 zh_CN.GBK GBK zh_CN.GB2312 GB ...

  5. Android---用动画来处理布局的变化

    本文译自:http://developer.android.com/training/animation/layout.html 布局动画一种系统预装的动画,每次布局配置发生变化时,系统会运行它.你所 ...

  6. [Angular 2] Custom Validtors

    Create a custom validtor which only accepts the string start with '123'; function skuValidator(contr ...

  7. C++类中静态变量

    以下是对类中static变量的一点解说    ===============================================    静态数据成员的用法和注意事项例如以下:       ...

  8. [转] GCC __builtin_expect的作用

    http://blog.csdn.net/shuimuniao/article/details/8017971 将流水线引入cpu,可以提高cpu的效率.更简单的说,让cpu可以预先取出下一条指令,可 ...

  9. Android开发环境搭建详细图解

    所谓Android的开发环境,主要是以下两个组件,Android Software Developer Kit(Android软件开发工具包)和Eclipse(编辑器,提供很多方便功能)两大块,下面分 ...

  10. 优雅退出 Android 应用程序的 6 种方式

    我们先来看看几种常见的退出方法(不优雅的方式) 一.容器式 建立一个全局容器,把所有的Activity存储起来,退出时循环遍历finish所有Activity import java.util.Arr ...