使用use index优化sql查询的详细介绍

 更新时间:2013年06月11日 17:11:14   作者:  
本篇文章是对使用use index优化sql查询进行了详细的分析介绍,需要的朋友参考下

先看一下arena_match_index的表结构,大家注意表的索引结构

复制代码 代码如下:

CREATE TABLE `arena_match_index` (
  `tid` int(10) unsigned NOT NULL DEFAULT '0',
  `mid` int(10) unsigned NOT NULL DEFAULT '0',
  `group` int(10) unsigned NOT NULL DEFAULT '0',
  `round` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `day` date NOT NULL DEFAULT '0000-00-00',
  `begintime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  UNIQUE KEY `tm` (`tid`,`mid`),
  KEY `mid` (`mid`),
  KEY `begintime` (`begintime`),
  KEY `dg` (`day`,`group`),
  KEY `td` (`tid`,`day`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

接着看下面的sql:
复制代码 代码如下:

SELECT round  FROM arena_match_index WHERE `day` = '2010-12-31' AND `group` = 18 AND `begintime` < '2010-12-31 12:14:28' order by begintime LIMIT 1;

这条sql的查询条件显示可能使用的索引有`begintime`和`dg`,但是由于使用了order by begintime排序mysql最后选择使用`begintime`索引,explain的结果为:
复制代码 代码如下:

mysql> explain SELECT round  FROM arena_match_index  WHERE `day` = '2010-12-31' AND `group` = 18 AND `begintime` < '2010-12-31 12:14:28' order by begintime LIMIT 1;
+----+-------------+-------------------+-------+---------------+-----------+---------+------+--------+-------------+
| id | select_type | table             | type  | possible_keys | key       | key_len | ref  | rows   | Extra       |
+----+-------------+-------------------+-------+---------------+-----------+---------+------+--------+-------------+
|  1 | SIMPLE      | arena_match_index | range | begintime,dg  |<STRONG> </STRONG>begintime<STRONG> </STRONG>| 8       | NULL | 226480 | Using where |
+----+-------------+-------------------+-------+---------------+-----------+---------+------+--------+-------------+

explain的结果显示使用`begintime`索引要扫描22w条记录,这样的查询性能是非常糟糕的,实际的执行情况也是初次执行(还未有缓存数据时)时需要30秒以上的时间。

实际上这个查询使用`dg`联合索引的性能更好,因为同一天同一个小组内也就几十场比赛,因此应该优先使用`dg`索引定位到匹配的数据集合再进行排序,那么如何告诉mysql使用指定索引呢?使用use index语句:

复制代码 代码如下:

mysql> explain SELECT round  FROM arena_match_index use index (dg) WHERE `day` = '2010-12-31' AND `group` = 18 AND `begintime` < '2010-12-31 12:14:28' order by begintime LIMIT 1;
+----+-------------+-------------------+------+---------------+------+---------+-------------+------+-----------------------------+
| id | select_type | table             | type | possible_keys | key  | key_len | ref         | rows | Extra                       |
+----+-------------+-------------------+------+---------------+------+---------+-------------+------+-----------------------------+
|  1 | SIMPLE      | arena_match_index | ref  | dg            | dg   | 7       | const,const |  757 | Using where; Using filesort |
+----+-------------+-------------------+------+---------------+------+---------+-------------+------+-----------------------------+

explain结果显示使用`dg`联合索引只需要扫描757条数据,性能直接提升了上百倍,实际的执行情况也是几乎立即就返回了查询结果。

在最初的查询语句中只要把order by begintime去掉,mysql就会使用`dg`索引了,再次印证了order by会影响mysql的索引选择策略!

复制代码 代码如下:

mysql> explain SELECT round  FROM arena_match_index  WHERE `day` = '2010-12-31' AND `group` = 18 AND `begintime` < '2010-12-31 12:14:28'  LIMIT 1;
+----+-------------+-------------------+------+---------------+------+---------+-------------+------+-------------+
| id | select_type | table             | type | possible_keys | key  | key_len | ref         | rows | Extra       |
+----+-------------+-------------------+------+---------------+------+---------+-------------+------+-------------+
|  1 | SIMPLE      | arena_match_index | ref  | begintime,dg  | dg   | 7       | const,const |  717 | Using where |
+----+-------------+-------------------+------+---------------+------+---------+-------------+------+-------------+

通过上面的例子说mysql有时候也并不聪明,并非总能做出最优选择,还是需要我们开发者对它进行“调教”!

相关文章

  • mysql如何将id重新修改为递增

    mysql如何将id重新修改为递增

    这篇文章主要介绍了mysql如何将id重新修改为递增,本文模拟场景结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • Windows 本地安装 Mysql8.0图文教程

    Windows 本地安装 Mysql8.0图文教程

    本文介绍了如何在Windows本地安装Mysql8.0。从下载Mysql8.0安装包,运行安装程序,配置初始设置到启动Mysql服务等详细步骤进行了讲解。
    2023-04-04
  • MySQL中的空格处理方法

    MySQL中的空格处理方法

    在MySQL中,空格是一个特殊的字符,本文主要介绍了MySQL中的空格处理方法,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • MYSQL加密和压缩函数详解以及实战(附示例)

    MYSQL加密和压缩函数详解以及实战(附示例)

    这篇文章主要给大家介绍了关于MYSQL加密和压缩函数详解以及实战的相关资料,加密函数主要用来对数据进行加密和界面处理,以保证某些重要数据不被别人获取,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • mysql 8.0.17 安装配置图文教程

    mysql 8.0.17 安装配置图文教程

    这篇文章主要为大家详细介绍了mysql 8.0.17 安装配置图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • 深入解析mysql中order by与group by的顺序问题

    深入解析mysql中order by与group by的顺序问题

    本篇文章是对mysql中order by与group by的顺序问题进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • MySQL与PHP的基础与应用专题之内置函数

    MySQL与PHP的基础与应用专题之内置函数

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,本系列将带你掌握php与mysql的基础应用,本篇MySQL的内置函数开始
    2022-02-02
  • MySQL查询指定字段不是数字与逗号的sql

    MySQL查询指定字段不是数字与逗号的sql

    今天小编遇到一个问题因为编辑的不细心不小心将关键词写到相关文章里面导致页面无法生成,这里用sql语言将这些内容获取出来
    2020-02-02
  • MySQL外键设置的方法实例

    MySQL外键设置的方法实例

    这篇文章主要介绍了MySQL外键设置的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • MySQL笔记之索引的使用

    MySQL笔记之索引的使用

    索引是创建在表上的,对数据库表中一列或多列的值进行排序的一种结构其作用主要在于提高查询的速度,降低数据库系统的性能开销
    2013-05-05

最新评论