前言

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. 【动态规划】【二分】【最长上升子序列】Vijos P1028 魔族密码

    题目链接: https://vijos.org/p/1028 题目大意: 给N个字符串(N<=2000),求能组成词链的单词最多有几个. 如果在一个由一个词或多个词组成的表中,除了最后一个以外, ...

  2. String拼接也有用加号更好的时候

    做String拼接时用StringBuilder(或StringBuffer)好还是直接用+号性能好?一般来说是前者,不过也有用加号略好的时候.首先我一直认为用+号有很好的可读性,而且当String拼 ...

  3. 在eclipse下编译hadoop2.0源码

    Hadoop是一个分布式系统基础架构,由apache基金会维护并更新.官网地址: http://hadoop.apache.org/ Hadoop项目主要包括以下4个模块: Hadoop Common ...

  4. Selenium终极自动化测试环境搭建(一) Selenium+Eclipse+Junit+TestNG

    Selenium终极自动化测试环境搭建(一)Selenium+Eclipse+Junit+TestNG 第一步 安装JDK JDk1.7. 下载地址:http://www.oracle.com/tec ...

  5. 【.NET调用Python脚本】C#调用python requests类库报错 'module' object has no attribute '_getframe' - IronPython 2.7

    最近在开发微信公众号,有一个自定义消息回复的需求 比如用户:麻烦帮我查询一下北京的天气? 系统回复:北京天气,晴,-℃... 这时候需要根据关键字[北京][天气],分词匹配需要执行的操作,然后去调用天 ...

  6. HDOJ 5184 Brackets 卡特兰数扩展

    既求从点(0,0)仅仅能向上或者向右而且不穿越y=x到达点(a,b)有多少总走法... 有公式: C(a+b,min(a,b))-C(a+b,min(a,b)-1)  /// 折纸法证明卡特兰数: h ...

  7. Linux 调度器模拟

    http://www.ibm.com/developerworks/cn/linux/l-linux-scheduler-simulator/ LinSched LinSched 是驻留在用户空间中的 ...

  8. log4j配置文件详解---转

    使用步骤注意: 1. 从http://logging.apache.org/log4j/1.2/ 下载文件 2. 在src目录下加入log4j.properties,将jar包放入build -pat ...

  9. HDU3480

    题意:给你n个数,然后让你分成m个集合,每个集合有一个值(最大值减最小值,然后平方),求整个集合的可能最小值. 思路:因为每个集合里的值只和最大和最小值有关,所以很容易想到先排序,然后用DP可求得解, ...

  10. HDU5308-脑补-对拍

    先贴上对拍的结果: 感想:可以明显发现下标相差1的关系,所以对付这种需要大量脑补的水题,真的蛋疼,以前没用过对拍,只知道有这么回事,调程序什么的都是手算,人工模拟(经常大脑发热,严重缺氧不足),所以试 ...