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. ANDROID_MARS学习笔记_S02_006_APPWIDGET2_PendingIntent及RemoteViews实现widget绑定点击事件

    一.代码流程 1.ExampleAppWidgetProvider的onUpdate(Context context, AppWidgetManager appWidgetManager, int[] ...

  2. 《ArcGIS Engine+C#实例开发教程》第八讲 属性数据表的查询显示

    原文:<ArcGIS Engine+C#实例开发教程>第八讲 属性数据表的查询显示 第一讲 桌面GIS应用程序框架的建立 第二讲 菜单的添加及其实现 第三讲 MapControl与Page ...

  3. Django中的Model继承

    Django 中的 model 继承和 Python 中的类继承非常相似,只不过你要选择具体的实现方式:让父 model 拥有独立的数据库:还是让父 model 只包含基本的公共信息,而这些信息只能由 ...

  4. UC何小鹏:移动互联网创业需警惕五大“不靠谱

    http://tech.qq.com/a/20140121/012443.htm 腾讯科技 启言 1月21日报道 移动互联网创业很容易犯错误,一不小心就陷入“坑”中.UC也是如此.近日,UC创始人何小 ...

  5. NTP 服务器配置

    1.yum安装ntp 1 yum install ntp* 2.更新时间 1 ntpdate 202.120.2.101 3.加入任务计划 1 2 crontab -e */10 * * * * nt ...

  6. [swustoj 411] 售货员的难题

    售货员的难题(0411) Time limit(ms): 5000 Memory limit(kb): 65535 Submission: 1744 Accepted: 200 Description ...

  7. 【转】Android 源码编译make的错误处理--不错

    原文网址:http://blog.csdn.net/ithomer/article/details/6977386 Android源码下载:官方下载 或参考android源码下载方式 Android编 ...

  8. SharePoint Services 数据库表

    转:http://dugan.bokee.com/630446.html 以下是Microsoft Windows SharePoint Services架构中数据库列表. Configuration ...

  9. 从零开始学习jQuery (八) 插播:jQuery实施方案

    一.摘要 本系列文章将带您进入jQuery的精彩世界, 其中有很多作者具体的使用经验和解决方案,  即使你会使用jQuery也能在阅读中发现些许秘籍. 本篇文章属于临时插播,  用于介绍我在本公司的j ...

  10. NullableKey:解决Dictionary中键不能为null的问题 zt

    2012-12-29 02:26 by 老赵, 1745 visits 众所周知,.NET中Dictionary的键不能为null,否则会抛出NullReferenceException,这在某些时候 ...