Posted by Money Talks on 2012/02/24 |

第一篇 序章
第二篇 连接优化
第三篇 索引优化
第四片 查询优化
第五篇 到实战中去

查询优化

查询优化涉及到用户查询数据时使用到的索引、排序、group 等操作,以及其书写习惯。(原文链接http://ddbiz.com/?p=990)

  1. 影响查询的服务器参数调整

    除了用户的查询习惯外,在整个数据查询的处理期间,mysql服务器中有些参数同样影响这些查询的执行,比如临时表、临时文件等。

    1. max_heap_table_size

      命令行参数: –max_heap_table_size=#
      ini/cnf定义: max_heap_table_size
      mysql 变量: max_heap_table_size
      全局变量,可动态调整, 默认值为16M, 可调整范围32bitOS 16k到4G,64bitOS 16k到你能提供的可用内存量(最大1Zetta)

      用于存储引擎为 MEMORY 的用户表

    2. tmp_table_size

      命令行参数: –tmp_table_size=#
      ini/cnf定义: tmp_table_size
      mysql 变量: tmp_table_size
      全局变量,可动态调整, 默认值以系统设定,最大值4G

      tmp_table_size是mysql在执行group时,生成的内存表的大小限制,和max_heap_table_size一样,这是一个字节大小值。在系统中此值将和要查询的表的行长进行计算,用以决定mysql可以装载的表的行数。如果查询中的一个限制超过此值,在3.x以后的版本中,mysql会自动把这个临时表改换为磁盘文件:MyISAM 引擎。用户主动创建的内存表是不包含在此限制中的。

      根据状态 :created_tmp_disk_tables 和 created_tmp_tables 来判定是否需要增加 tmp_table_size。

      受如下参数影响: max_head_table_size
      将影响如下参数:
      调整触发条件: 当created_tmp_disk_tables超过created_tmp_tables时,应该采取行动提高tmp_table_size值.

      特别说明:在下列情况下,内存临时表将不能发挥作用,mysql将直接使用 MyISAM

      • 表中有TEXT或者BLOB字段的情况
      • group by 或者 distinct 指定的字段中,存在有长度大于512字节的字段的情况
      • 在union/union all的select中,select 的字段有大于512字节的情况

      在下列情况,mysql有可能把内存临时表转换为MyISAM引擎

      • 查询中order by 与 group by 的字段不同
      • 在join查询中,order by或者 group by包含了不是第一个表的字段
      • 对distinct查询使用order by 排序

      注意:max_heap_table_size和tmp_table_size在分配给一个连接线程查询时,其取值是 min(max_heap_table_size,tmp_table_size), 如果一个站点的并发连接(show status like ‘thread_running’)很多,则系统内存会分配=min(max_heap_table_size,tmp_table_size) * (show status like ‘thread_running’)。比如并发1000的站点中,如果每个连接可分配的内存是16m,那么临时内存将被分配 16m * 1000=16g. 如果你有那么多内存可供使用,那么这不是问题,否则的话,还是要把 tmp_table_size设置小一些。
      当然,这也提示我们,在一个实时站点中,因为每个用户请求都不可能也不应该执行一个相对来讲很复杂或涉及很多记录的查询,对于一些统计工作,应该把统计用的数据库和online trancation数据库分开。

    3. max_tmp_tables

      根据文档(mysql5.5CE),此参数尚未启用!

    4. query_prealloc_size

      命令行参数: –query_prealloc_size=#
      ini/cnf定义: query_prealloc_size
      mysql 变量: query_prealloc_size
      全局变量,可动态调整, 默认值8k,最大值4G(32bitOS)或更高(64bitOS).
      query_prealloc_size 用于MySQL对SQL语句进行分析和执行的内存空间设定。当执行大的复杂的查询时,可以考虑针对SESSION增加此值。

    5. query_cache_* 查询结果缓存

      查询缓存是指两类:查询的SELECT语句以及查询的结果。这是一些列的系统变量设定:

      query_cache_size: select查询的结果缓存,0或者40k到4G(32bitOS)或更高(64bitOS),默认为0;
      query_cache_type: OFF:不缓存查询结果;ON:缓存除了SELECT SQL_NO_CACHE开头的所有查询结果;DEMAND:只缓存SELECT SQL_CACHE开头的查询结果。
      query_cache_limit: 可以缓存的最大值字节数。
      query_cache_min_res_unit:查询缓存分配的最小块大小,默认4k.
      query_cache_wlock_invalidate:MySQL5.5中默认为OFF,只是是否在WRITE lock存在时组织其他客户查询。

      注意事项:
      –>对于特别频繁的小查询来说(比如返回结果小于或者远小于query_cache_min_res_unit),很容易造成大量的内存碎片。
      –>对于结果集较大的查询来说,足够大的query_cache_min_res_unit可以提高系统的性能。
      通过对系统状态 Qcache_free_blocks 和 Qcache_lowmem_prunes 的查询来确定是否需要调整query_cache_min_res_unit。

      Qcache_free_blocks 查询缓存中空闲的内存块
      Qcache_lowmem_prunes 表明了因为查询缓存不足而有查询结果被从缓存中移除的数量。

  2. 深入理解Query Cache

    Query_cache_size在MySQL中默认是0,也就是说查询缓存默认是关闭的。既然查询缓存可以很好的提高用户的查询体验,为什么会被关闭呢?这要从MySQL的客户端编程来讲。Query_Cache_Size中的查询缓存,是依照查询语句作为键值来缓存结果的。查询语句必须要完全相同:大小写、空格、乃至查询变量。等等,为什么查询变量也会影响这个键值呢?原因很奇特:MySQL的客户端查询语句,使用的是直接变量替换,而不是像Oracle中那样的变量代入。看下面的这个查询例子:

    public function GetUserByAccount($dbname, $host, $username, $userpwd, $charset, $account)
    {
    $sql = "select id from tmp_userhere";
    if (CTextHelper::IsValidEmail($account))
    $sql .= ' where email=:key';
    else
    $sql .= ' where username=:key';
    $sql .= ' limit 3';
    $dsn = "mysql:dbname=".$dbname.";host=".$host;
    $dbh = new PDO($dsn, $username, $userpwd);
    $charset = isset($charset) ? $charset :"gbk";
    $this->dbh->exec("set names ".$charset);
    $sth = $dbh->prepare($sql);
    $sth->bindParam(':key', $account);
    $r = $sth->execute();
    if (!$r) return false;
    return $sth->fetchColumn(0);
    }

    尽管在客户端(php代码)中使用的是变量绑定, 而实际的服务器跟踪看到的却是:

    对于一个超大的数据表的查询来说,完全相同的查询几率太小了。所以完全可以省下这个Query Cache的设置。在我的某个大数据量的查询中,就让他是0吧。

  3. 用户的查询习惯

    有很多人为的因素都会影响到查询的效率。我不打算在这里一一列举,可以在 Top 10 SQL Performance Tips中看到各种各样的优化语句的技巧。

  4. Group By

    如果查询语句中使用到Group By,一般来说,MySQL将建立一个临时表,然后对数据进行计算和排序,这时是不使用索引的。如下面的查询:

    如果数据量很大,那么这个查询肯定会很慢。但是MySQL有一种方式,可以运行group by 通过索引来计算,条件是,group by中的所有字段都是一个索引中的列。

WORKING ON…,and KEEP EYES ON IT…

mysql优化之查询优化的更多相关文章

  1. mysql优化---订单查询优化:视图优化+索引创建

    订单的表结构采用了垂直分表的策略,将订单相关的不同模块的字段维护在不同表中 在订单处理这个页面,需要查询各种维度, 因此为了方便查询创建了v_sale_order视图(老版本) drop view v ...

  2. mysql优化---订单查询优化(1):视图优化+索引创建

    订单的表结构采用了垂直分表的策略,将订单相关的不同模块的字段维护在不同表中 在订单处理这个页面,需要查询各种维度, 因此为了方便查询创建了v_sale_order视图(老版本) drop view v ...

  3. mysql优化---订单查询优化:异步分页处理

    订单分页查询: 老的代码是顺序执行查询数据和计算总记录数,但是如果条件复杂的话(比如关联子表)查询的时间要超过20s种 public static PagedList<Map<String ...

  4. mysql优化---订单查询优化(2):异步分页处理

    订单分页查询: 老的代码是顺序执行查询数据和计算总记录数,但是如果条件复杂的话(比如关联子表)查询的时间要超过20s种 public static PagedList<Map<String ...

  5. mysql优化一之查询优化

    这一篇笔记的mysql优化是注重于查询优化,根据mysql的执行情况,判断mysql什么时候需要优化,关于数据库开始阶段的数据库逻辑.物理结构的设计结构优化不是本文重点,下次再谈 查看mysql语句的 ...

  6. MySQL优化 - 性能分析与查询优化(转)

    出处:  MySQL优化 - 性能分析与查询优化 优化应贯穿整个产品开发周期中,比如编写复杂SQL时查看执行计划,安装MySQL服务器时尽量合理配置(见过太多完全使用默认配置安装的情况),根据应用负载 ...

  7. Mysql优化系列(2)--通用化操作梳理

    前面有两篇文章详细介绍了mysql优化举措:Mysql优化系列(0)--总结性梳理Mysql优化系列(1)--Innodb引擎下mysql自身配置优化 下面分类罗列下Mysql性能优化的一些技巧,熟练 ...

  8. MySQL 5.6查询优化器新特性的“BUG” eq_range_index_dive_limit

    本文转自 http://www.imysql.cn 最近碰到一个慢SQL问题,解决过程有点小曲折,和大家分享下. SQL本身不复杂,表结构.索引也比较简单,不过个别字段存在于多个索引中. CREATE ...

  9. MySQL的limit查询优化

    MySQL的limit查询优化以下的文章主要是对MySQL limit查询优化的具体内容的介绍,我们大家都知道MySQL数据库的优化是相当重要的.其他最为常用也是最为需要优化的就是limit.MySQ ...

随机推荐

  1. mysql联合索引

    命名规则:表名_字段名1.需要加索引的字段,要在where条件中2.数据量少的字段不需要加索引3.如果where条件中是OR关系,加索引不起作用4.符合最左原则 https://segmentfaul ...

  2. 结构体page_cur_t

    /** Type of the index page */ typedef byte page_t; /** Index page cursor */ typedef struct page_cur_ ...

  3. Html——footer的使用

    html部分 <div class="container"> <div class="body"></div> <di ...

  4. 使用Win32/ATL建立窗口的过程

    有时候想写个几十kb的小程序,MFC实在是太大了,Win32有时又太麻烦,怎么办呢?用ATL写会更方便和轻量级一些 ATL和MFC不同的是,ATL并没有强制性封装WinMain函数,仅封装了WndPr ...

  5. jquery封装的选项卡

    ul,li,div{ margin:; padding:;} ul,li{ list-style:none;} .tab_wrap{ width:450px; margin: auto 50px; o ...

  6. HtmlParser应用,使用Filter从爬取到的网页中获取需要的内容

    htmlparser是一个纯的java写的html解析的库,它不依赖于其它的java库文件,主要用于改造或提取html.它能超高速解析html,而且不会出错.现在htmlparser最新版本为2.0. ...

  7. 由点击页面其它地方隐藏div所想到的jQuery的delegate

    对于这个问题一般有两种思路,这两种思路都会利用事件冒泡这一原理,想要详细了解Javascript事件机制可以看看JavaScript与HTML交互——事件,这不是本文重点,所以这里只是简单介绍一下事件 ...

  8. 嵌入式 uboot、fs、kernel制作和烧录简记-hi3518c

    NULL RAM : mkdir ramdisk_test  临时挂在点 dd if=/dev/zero of=rootfs.ramdisk bs=1k count=10000 建立空硬盘//1500 ...

  9. STL总结之deque

    STL中deque是我们常说的双端队列,既可以从头添加元素,也可以从尾部添加元素,deque的成员函数和vector的成员函数十分相似,但是它们的内部实现却又很多不同.   deque的模板声明: t ...

  10. [Android]在Dagger 2中Activities和Subcomponents的多绑定(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/6266442.html 在Dagger 2中Activities ...