当前位置:  数据库>mysql

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

    来源: 互联网  发布时间:2014-10-09

    本文导语:  先看一下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 NO...

先看一下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  | begintime | 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有时候也并不聪明,并非总能做出最优选择,还是需要我们开发者对它进行“调教”!

    
 
 

您可能感兴趣的文章:

  • tcmalloc内存泄露优化c++开源库下载,安装及使用介绍
  • 怎么没有讨论XML的?哪位高手介绍介绍在JAVA中怎么使用XML?
  • c/c++预处理命令预#,##使用介绍
  • 急!!谁了解macintosh?能不能给我介绍介绍?是不是跟linux差不多?使用开发工具JDK,这是不是不JAVA?
  • mongodb介绍及使用场景
  • 谁能告诉我哪里能找到java包内部类及方法使用介绍
  • linux下c/c++使用hash_map方法介绍
  • 可以介绍一下怎么使用RHN 来升级linux系统吗?
  • c++类库Boost::bimap(双向映射)介绍及使用实例
  • 有什么好的介绍UNIX使用和管理的书吗?UNIX下最常用的数据库是什么?
  • 网站如何使用cookie以及cookie相关的规范介绍
  • 谁能否介绍在jbuilder7下怎么使用structs开发web程序么?谢谢!!!!
  • linux下objdump命令用法介绍及如何使用objdump命令进行反汇编
  • C#中的switch case使用介绍
  • 以NetBeans IDE为例介绍如何使用XML中Schema语言
  • Oracle中SQL语句连接字符串的符号使用介绍
  • TinyXML(c++下操作xml的库)介绍,下载地址及使用代码举例
  • 谁来介绍一点 JSP 中使用 cookie 的资料?(34分)
  • c++ stl multimap基本操作使用技巧详细介绍
  • 基于jdbc处理Clob的使用介绍
  • 新装的Linux使用root用户不能使用FTP? iis7站长之家
  • 请详细介绍一下JTree的使用方法,88分奉送......................
  • mysql的SQL_NO_CACHE(在查询时不使用缓存)和sql_cache用法
  • HBase上使用SQL查询 Phoniex
  • 问个比较菜的问题: LINUX如何查询C函数的使用方法?
  • !!Unix下如何在程序中查询出剩余磁盘空间?应该使用什么函数?
  • 在SQL中使用convert函数进行日期的查询的代码
  • linux下面如何查询某个进程正在使用的socket句柄数量
  • Oracle层次查询和with函数的使用示例
  • 在SQL Server中使用SQL语句查询一个存储过程被其它所有的存储过程引用的存储过程名
  • 数据库查询排序使用随机排序结果示例(Oracle/MySQL/MS SQL Server)
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • C++ I/O 成员 tellg():使用输入流读取流指针
  • 在测试memset函数的执行效率时,分为使用Cash和不使用Cash辆种方式,该如何控制是否使用缓存?
  • C++ I/O 成员 tellp():使用输出流读取流指针
  • 求ibm6000的中文使用手册 !从来没用过服务器,现在急需使用它,不知如何使用! 急!!!!!
  • Python不使用print而直接输出二进制字符串
  • 请问:在使用oracle数据库作开发时,是使用pro*c作开发好些,还是使用库函数如oci等好一些啊?或者它们有什么区别或者优缺点啊?
  • Office 2010 Module模式下使用VBA Addressof
  • 急求结果!!假设一个有两个元素的信号量集S,表示了一个磁带驱动器系统,其中进程1使用磁带机A,进程2同时使用磁带机A和B,进程3使用磁带机B。
  • windows下tinyxml.dll下载安装使用(c++解析XML库)
  • c#中SAPI使用总结——SpVoice的使用方法
  • sharepoint 2010 使用STSNavigate函数实现文件下载举例
  • 使用了QWidget的程序,如何使用后台程序启动它?
  • 使用libpcap读取tcpdump抓取的文件并解析c代码实例
  • 共享内存一般是怎么使用的,是同消息队列配合使用么
  • 在div中使用css让文字底部对齐的方法
  • Jsp可否使用带有GUI的JavaBean,如何使用?
  • Python namedtuple(命名元组)使用实例
  • asp程序使用的access在Linux下如何使用!
  • MySQL Workbench的下载安装与使用教程
  • 新装的Linux使用root用户不能使用FTP?
  • nginx Windows版相关问题及使用说明
  • LINUX下使用Eclipse,如何使用交叉编译器?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3