精华内容
下载资源
问答
  • 2020-08-10 11:09:57

    mysql查询速度优化

    这是type级别 越左边 查询速度越快
    system>const>eq_ref>ref>range>index>ALL

    这是我查询的 eq_ref是唯一索引时 才能达到 all的话说明查询的条件没有建立索引 所以是全表查询这样就很慢 很慢 也很浪费时间的

    怎么样才能让type靠左呢 就是建立索引 最左边的俩级 基本达不到 我们让查询type达到第三级和第四级就很好了 为什么这么说呢?
    表主键 唯一索引也只能达到 eq_ref 级别的
    如果不做索引的话 肯定都是ALL了…

    Type级别解释

    1.system级别

    1.只有一条数据的系统表

    2.或衍生表只能有一条数据的主查询

    很明显 实际开发当中 我们是不会只有一条数据的

    2.const级别

    1.仅仅能查出一条的SQL语句并且用于Primary key 或 unique索引;
    SELECT * from shop s where s.id=?
    主键索引 唯一索引 和 unique索引 达到这个级别 我们写sql 要根据公司的业务去写 这个情况也很难达到的

    3.eq_ref级别

    唯一性索引:对于每个索引键的查询,返回匹配唯一行数据(有且只有1个,不能多,不能0);
    比如你select …from 一张表 where 比方说有一个字段 name = 一个东西,也就是我们以name作为索引,假设我之前给name加了一个索引值,我现在根据name去查,查完后有20条数据,我就必须保证这二十条数据每行都是唯一的,不能重复不能为空!

    只要满足以上条件,你就能达到eq_ref,当然前提是你要给name建索引,如果name连索引都没,那你肯定达不到eq_ref;

    此种情况常见于唯一索引和主键索引;

    比如我根据name去查,但是一个公司里面或一个学校里面叫name的可能不止一个,一般你想用这个的时候,就要确保你这个字段是唯一的,id就可以,你可以重复两个张三,但是你身份证肯定不会重复;

    添加唯一键语法:alter table 表名 add constraint 索引名 unique index(列名)

    检查字段是否唯一键:show index form 表名;被展示出来的皆是有唯一约束的;

    4.ref级别

    ref 级别的 问题不大

    非唯一性索引:对于每个索引键的查询,返回匹配的所有行(可以是0,或多个)

    假设有俩张三 我建立了 非唯一索引 那么查出来就是这个级别拉 是不是很简单

    5.range级别

    检索指定范围的行,查找一个范围内的数据,where后面是一个范围查询 (between,in,> < >=);
    in 有时 有可能会失效,导致为ALL ;

    (in失效的情况 我是没试出来…) 你们可以试试

    6.index级别

    把索引的数据全查出来 就是这个级别了

    7.ALL级别

    不做索引 就是all级别咯

    总结

    所以在做表的时候 频繁查询的 一定要建立索引
    当然建立索引会放慢插入表数据的时间 不过一张表5-8个索引还是很常见的

    好了 看完觉得还可以 给小编点个赞呗~

    看情况有空在更新一波关于索引的 ~

    更多相关内容
  • MySQL查询优化

    千次阅读 2021-04-27 10:17:07
    索引是什么 索引是数据库存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其当表中的数据量越来越大时。 MySQL索引数据结构

    一、优化的思路和原则有哪些

    1、 优化更需要优化的查询
    2、 定位优化对象的性能瓶颈
    3、 明确优化的目标
    4、 从Explain入手
    5、 多使用 profile
    6、 永远用小结果集驱动大结果集
    7、 尽可能在索引中完成排序
    8、 只取出自己需要的字段(Columns)
    9、 仅仅使用最有效的过滤条件
    10、尽可能避免复杂的join

    1、优化更需要优化的查询

     高并发的低消耗(相对)的查询 对整个系统影响远大于低并发高消耗的查询。

    2、定位优化对象的性能瓶颈

     在拿到一条需要优化的查询时,我们首先要判断出这个查询的瓶颈到底是IO还是CPU。到底是数据库访问消耗多还是数据的运算(如分组排序)消耗多。

    3、明确优化的目标

     了解数据库目前整体状态,就能知道数据库所能承受的最大压力,也就是我们知道最悲观状况;
     要把握该查询相关的数据库对象信息,我们就能知道最理想和最糟糕状态下需要消耗多少资源;
     要知道该查询在应用系统中的地位,我们可以分析出改查询可以占用系统资源的比例,也能够知道该查询的效率对客户的体验影响有多大。

    4、从Explain入手

    Explain能够告诉你这个查询在数据库中是一个什么样的执行计划来实现的。首先我们需要有个目标,通过不断调整尝试,再借助Explain来验证结果是否满足自己的需求,直到得到预期的结果。

    5、永远用小结果集驱动大结果集

     很多人喜欢在SQL优化的时候说用“小表驱动大表”,这个说法是不严谨的。因为大表经过where条件过滤后返回的结果集并不一定就比小表所返回的结果集大,这个时候还用大表驱动小表,就会得到相反的性能效果。
     这样的结果也非常容易理解,在 MySQL 中的 Join,只有 Nested Loop 一种 Join 方式,也就是MySQL 的 Join 都是通过嵌套循环来实现的。驱动结果集越大,所需要循环的次数就越多,那么被驱动表的访问次数自然也就越多,而每次访问被驱动表,即使需要的逻辑 IO 很少,循环次数多了,总量自然也不可能很小,而且每次循环都不能避免的需要消耗CPU,所以 CPU 运算量也会跟着增加。所以,如果我们仅仅以表的大小来作为驱动表的判断依据,假若小表过滤后所剩下的结果集比大表多很多,结果就是给嵌套循环带来更多的循环次数,反之,所需要的循环次数就会更少,总体 IO 量和 CPU 运算量也会少。而且,就算是非 Nested Loop 的 Join 算法,如 Oracle 中的 Hash Join,同样是小结果集驱动大的结果集才是最优的选择。
     所以,在优化 Join Query 的时候,最基本的原则就是“小结果集驱动大结果集”,通过这个原则来减少嵌套循环中的循环次数,达到减少 IO 总量以及 CPU 运算的次数。

    6、只取出自己需要的字段(Columns)

     对于任何查询,返回的数据都是需要通过网络数据包传输给客户端,如果取出的Column越多,需要传输的数据量自然会越大,不论从网络带宽还是网络传输缓冲区来看,都是一种浪费。

    7、仅仅使用最有效的过滤条件

     举个例子一个用户表user有id和nick_name等字段,索引是id和nike_name两个索引,下面是两个查询语句

    #1
    select * from user where id = 1 and nick_name = 'zs';
    #2
    selet * from user where id = 1
    

     两个查询得到结果是一样的,但是第一个语句用到的索引占用空间是比第二个语句大很多的。占用空间大也代表着要读取的数据量也更多。,也就是说2的查询语句才是最优查询。

    8、避免复杂的join查询

     我们的查询语句所涉及到的表越多,所需要锁定的资源就越多。也就是说,越复杂的 Join 语句,所需要锁定的资源也就越多,所阻塞的其他线程也就越多。相反,如果我们将比较复杂的查询语句分拆成多个较为简单的查询语句分步执行,每次锁定的资源也就会少很多,所阻塞的其他线程也要少一些。
     可能很多人会有疑问,将复杂 Join 语句分拆成多个简单的查询语句之后,那不是我们的网络交互就会更多了吗?网络延时方面的总体消耗也就更大了啊,完成整个查询的时间不是反而更长了吗?是的,这种情况是可能存在,但也并不是肯定就会如此。我们可以再分析一下,一个复杂的查询语句在执行的时候,所需要锁定的资源比较多,可能被别人阻塞的概率也就更大,如果是一个简单的查询,由于需要锁定的资源较少,被阻塞的概率也会小很多。所以 较为复杂的连接查询也有可能在执行之前被阻塞而浪费更多的时间。而且我们的数据库所服务的并不是单单这一个查询请求,还有很多很多其他的请求,在高并发的系统中,牺牲单个查询的短暂响应时间而提高整体处理能力也是非常值得的。优化本身就是一门平衡与取舍的艺术,只有懂得取舍,平衡整体,才能让系统更优。

    二、利用 Explain和Profiling

    1、Explain使用

    各种信息展示

    字段说明
    ID执行计划中查询的序列号
    Select_type查询类型:
    DEPENDENT SUBQUERY : 子查询中内层的第一个SELECT,依赖于外部查询结果集;
    DEPENDENT UNION:子查询中的UNION中从第二个SELECT 开始的后面所有SELECT,同样依赖于外部查询结果集;
    PRIMARY: 子查询中的最外层查询,不是主键查询;
    SUBQUERY:子查询内层查询的第一个SELECT,结果不依赖于外部结果集;
    UNCACHEABLE SUBQUERY:结果集无法缓存的子查询;
    UNION:UNION语句中第二个SELECT开始的后面所有SELECT,第一个SELECT为PRIMARY
    UNION RESULT:UNION中的合并结果
    Table所访问的数据库中表名称
    TYPE访问方式:
    ALL: 全表扫描
    const: 常量,最多只有一条记录匹配,由于是常量,所以实际上只需要读一次
    eq_ref: 最多只有一条匹配结果,一般是主键或者唯一索引来访问的
    index: 全索引扫描
    range: 索引范围扫描
    ref: jion语句中被驱动表索引的引用查询
    system: 系统表,表中只有一行数据
    Possible_keys可能用到的索引
    Key使用的索引
    Key_len索引长度
    Rows估算出来的结果集记录条数
    Extra额外信息

    2、Profiling使用

    该工具可以获取一条Query在整个执行过程中多种资源消耗情况,如CPU,IO,IPC,SWAP等,以及发生PAGE FAULTS, CONTEXT SWITCHE等等,同时还能得到该Query执行过程中MySQL所调用的各个函数在源文件中的位置。

    1、开启profiling参数 1-开启,0-关闭

    #开启profiling参数 1-开启,0-关闭
    set profiling=1;
    SHOW VARIABLES LIKE '%profiling%';
    

    2、然后执行一条Query
    在这里插入图片描述
    3、获取系统保存的profiling信息

    show PROFILES;
    

    在这里插入图片描述4、通过QUERY_ID获取profile的详细信息(下面以获取CPU和IO为例)

    show profile cpu, block io for QUERY 7;
    

    在这里插入图片描述

    三、合理利用索引

    1、什么是索引

     简单来说,在关系型数据库中,索引是一种单独的,物理的对数据库表中一列或者多列的值进行排序的一种存储结构。就像书的目录,可以根据目录中的页码快速找到需要的内容。
     在MySQL中主要有四种类型索引,分别是:B-Tree索引,Hash索引,FullText索引,R-Tree索引,下面主要说一下我们常用的B-Tree索引,其他索引可以自行查找资料。

    2、索引的数据结构

     一般来说,MySQL中的B-Tree索引的物理文件大多数都是以平衡树的结构来存储的,也就是所有实际需要存储的数据都存储于树的叶子节点,二到任何一个叶子节点的最短路径的长度都是完全相同的。MySQL中的存储引擎也会稍作改造,比如Innodb存储引擎的B-Tree索引实际上使用的存储结构是B+Tree,在每个叶子节点存储了索引键相关信息之外,还存储了指向相邻的叶子节点的指针信息,这是为了加快检索多个相邻的叶子节点的效率。
     在Innodb中,存在两种形式的索引,一种是聚簇形式的主键索引,另外一种形式是和其他存储引擎(如MyISAM)存放形式基本相同的普通B-Tree索引,这种索引在Innodb存储引擎中被称作二级索引。
    在这里插入图片描述
     图示中左边为 Clustered 形式存放的 Primary Key,右侧则为普通的 B-Tree 索引。两种索引在根节点和 分支节点方面都还是完全一样的。而 叶子节点就出现差异了。在主键索引中,叶子结点存放的是表的实际数据,不仅仅包括主键字段的数据,还包括其他字段的数据,整个数据以主键值有序的排列。而二级索引则和其他普通的 B-Tree 索引没有太大的差异,只是在叶子结点除了存放索引键的相关信息外,还存放了 Innodb 的主键值。
     所以,在 Innodb 中如果通过主键来访问数据效率是非常高的,而如果是通过二级索引来访问数据的话,Innodb 首先通过二级索引的相关信息,通过相应的索引键检索到叶子节点之后,需要再通过叶子节点中存放的主键值再通过主键索引来获取相应的数据行。
     MyISAM 存储引擎的主键索引和非主键索引差别很小,只不过是主键索引的索引键是一个唯一且非空的键而已。而且 MyISAM 存储引擎的索引和 Innodb 的二级索引的存储结构也基本相同,主要的区别只是 MyISAM 存储引擎在叶子节点上面除了存放索引键信息之外,再存放能直接定位MyISAM 数据文件中相应的数据行的信息(如 Row Number),但并不会存放主键的键值信息。

    3、索引的利弊

    优点: 提高数据的检索速度,降低数据库的IO成本;
    缺点:查询需要更新索引信息带来额外的资源消耗,索引还会占用额外的存储空间

    4、如何判断是否需要建立索引

     上面说了索引的利弊,我们知道索引并不是越多越好,索引也会带来副作用。那么我们该怎么判断是否需要建立索引呢?
    1、 较频繁的作为查询条件的字段应该创建索引;
    2、更新频繁的字段不适合建立索引;
    3、唯一性太差的不适合创建索引(诸如逻辑删除字段,状态字段,性别字段);
    4、不出现在where中的字段不适合创建索引;

    5、单索引还是组合索引?

     在一般的应用场景,只要不是其中某个过滤字段在大多数场景下都能过滤90%以上的数据,而且其他的过滤字段会频繁更新,我一般更倾向于创建组合索引,尤其是在并发量较高的场景下更是如此。因为并发量搞的时候,即使我们为每个查询节省很少IO消耗,但因为执行量非常大,所节省的资源总量还是很大的。
     但是我们创建组合索引并不是说查询条件中的所有字段都要放在一个索引中,我们应该让一个索引被多个查询所利用,尽量减少索引的数量,以此来减少更新的成本和存储成本。
     MySQL为我们提供了一个减少优化索引自身的功能,那就是“前缀索引”。也就是我们可以仅仅使用某个字段的前面部分内容作为索引键来索引该字段,减少索引所占用的空间和提高索引的访问效率。当然前缀索引只适合前缀比较随机重复很少的字段。

    6、索引的选择

    1、对于单键索引 ,尽量针对当前查询过滤最好的索引;
    2、在选择组合索引的时候,当前查询中过滤性最好的字段在索引字段顺序中排列越靠前越好;
    3、在选择组合索引的时候,尽量选择可以能够包含当前查询的where字句中更多字段的索引;
    4、尽可能通过分析统计信息和调整查询的写法来达到选择合适的的索引来减少通过人为Hint控制索引的选择,以为这样后期维护成本会很高。

    7、MySQL索引的限制

    1、MyISAM存储引擎索引键长总和不能超过1000字节;
    2、BLOB和TEXT类型字段只能创建前缀索引;
    3、MySQL不支持函数索引;
    4、使用 != 或者<>时候,MySQL索引无法使用;
    5、过滤字段使用函数运算后,MySQL索引无法使用;
    6、jion语句中近字段类型不一致的时候,MySQL索引无法使用;
    7、使用like如果是前匹配(如:’%aaa’),MySQL索引无法使用;
    8、使用非等值查询的时候,MySQL无法使用HASH索引;
    9、字符类型是数字的时候要使用 =‘1’ 不可以直接使用 = 1;
    10、不要使用or可以用in代替或者 union all;
    11、join的时候两张表的字符集不一致也会导致索引失效

    8、Join原理以及优化

    Join原理:在MySQL中,只有一种join算法,就是大名鼎鼎的嵌套循环,实际上就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。如果还有近参与,再通过前面的近结果集作为循环基础数据,再循环遍历,如此往复。
    优化
    1、尽可能减少Join语句中的循环总次数(还记得前面说过的小结果集驱动大结果集吗);
    2、优先优化内层循环;
    3、保证Join语句中被驱动表上的Join条件字段已经被索引;
    4、当无法保证被驱动表的Join条件字段被索引且内存资源充足条件下,不要吝啬Join buffer的设置(join buffer只会在 All,index,range才能够用的上);

    9、ORDER BY优化

    在MySQL中,ORDER BY的实现只有两种类型:
     1、通过有序的索引直接取得有序的数据,这样不用进行任何排序操作即可得到客户端要求的有序数据;

     2、通过MySQL排序算法将存储的引擎中返回的数据进行排序然后再将排序后的数据返回给客户端。

    利用索引排序是最佳的方法,但是如果没有索引林勇的时候,MySQL主要两种算法实现:

     1、取出满足过滤条件的用于排序条件的字段以及可以直接定位到行数据的行指针信息,在 Sort Buffer 中进行实际的排序操作,然后利用排好序之后的数据根据行指针信息返回表中取得客户端请求的其他字段的数据,再返回给客户端;

     2、根据过滤条件一次取出排序字段以及客户端请求的所有其他字段的数据,并将不需要排序的字段存放在一块内存区域中,然后在 Sort Buffer 中将排序字段和行指针信息进行排序,最后再利用排序后的行指针与存放在内存区域中和其他字段一起的行指针信息进行匹配合并结果集,再按照顺序返回给客户端。

     第二种算法相较于第一种算法,主要就是减少了数据的二次访问。在排序好后,不需要再次回到表中取数据,节省了IO操作。当然第二种算法会消耗更多的内存,一种典型的以空间换取时间的优化方式。

     对于多表Join排序是先通过一个临时表将之前 Join 的结果集存放入临时表之后再将临时表的数据取到 Sort Buffer 中进行操作。

    对于非索引排序的时候,尽量选择第二种算法来进行排序,手段有:

     1、加大max_length_for_sort_data参数设置:
     MySQL决定使用哪个算法是通过参数max_length_for_sort_data来决定的,当我们返回字段的最大长度小于这个参数时候,MySQL就会选择第二中算法,相反则第一种算法。所以在有充足内存情况下,加大这个参数值可以让MySQL选择第二种算法;

     2、减少不必要的返回字段
     上面一样的道理,字段少了,就会尽量小于max_length_for_sort_data参数;

     3、增大sort_buffer_size参数设置(默认2M,基本满足我们要求,对于非高并发,内存充足情况下可适当调大些):
     增大 sort_buffer_size 并不是为了让 MySQL 可以选择改进版的排序算法,而是为了让 MySQL可以尽量减少在排序过程中对需要排序的数据进行分段,因为这样会造成 MySQL 不得不使用临时表来进行交换排序。

    四、最后

     调优其实是件很难的事情,调优也不限于上面的查询调优。诸如表的设计优化,数据库参数的调优,应用程序调优(减少循环操作数据库,批量新增;数据库连接池;缓存;)等等。当然还有很多调优技巧只有在实际实践中才能真正体会。只有自己以理论为基础,事实为依据,不断尝试去提升自己,才能成为一个真正的调优高手。

    展开全文
  • 描述 MySQL 查询优化器的工作原理。 MySQL 查询优化器主要为执行的查询决断最有效的路线
  • 针对 MySQL查询优化,非常给力!针对 MySQL查询优化,非常给力!针对 MySQL查询优化,非常给力!针对 MySQL查询优化,非常给力!针对 MySQL查询优化,非常给力!针对 MySQL查询优化,非常给力!
  • [玩转MySQL之六]MySQL查询优化

    千次阅读 2018-12-21 14:55:27
    注:由于查询优化器涉及面很广也比较复杂,作者也没有完全领会,本文主要来自书籍<...MySQL查询语句在数据库中的执行分为5个阶段,具体如下: 1.1 SQL输入 数据库接收用户输入的SQL语句,准备执行。 1.2...

    注:由于查询优化器涉及面很广也比较复杂,作者也没有完全领会,本文主要来自书籍<<数据库查询优化的艺术: 原理解析和SQL性能优化>>,如果涉及到版权,请告知作者,删除本文。

    一、查询语句的执行过程简介

    MySQL查询语句在数据库中的执行分为5个阶段,具体如下:

    1.1 SQL输入

    数据库接收用户输入的SQL语句,准备执行。

    1.2 语法分析

    对输入的SQL语句进行词法分析、语法分析,得到语法分析树。在这个阶段,输入的是一条SQL语句,输出的是一棵多叉树。

    1.3 语义检查

    根据语法树和系统的元信息进行语义检查,本阶段是对语法分析树进行逻辑判断,树的结构不发生变化。对语法分析树上的各个节点进行语义分析,判断对象是否存在、是否重名等,对不合语义的地方报告错误。

    1.4 SQL优化

    SQL优化通常包括两项工作:一是逻辑优化、二是物理优化。这两项工作都要对语法分析树的形态进行修改,把语法分析树变为查询树。其中,逻辑查询优化将生成逻辑查询执行计划。在生成逻辑查询执行计划过程中,根据关系代数的原理,把语法分析树变为关系代数语法树的样式,原先SQL语义中的一些谓词变化为逻辑代数的操作符等样式,这些样式是一个临时的中间状态,经过进一步的逻辑查询优化,如执行常量传递、选择下推等(如一些节点下移,一些节点上移),从而生成逻辑查询执行计划。
    在生成逻辑查询计划后,查询优化器会进一步对查询树进行物理查询优化。物理优化会对逻辑查询进行改造,改造的内容主要是对连接的顺序进行调整。SQL语句确定的连接顺序经过多表连接算法的处理,可能导致表之间的连接顺序发生变化,所以树的形态有可能调整。
    物理查询优化除了进行表的连接顺序调整外,还会使用代价估算模型对单个表的扫描方式、两表连接的连接算法进行评估,选择每一项操作中代价最小的操作为下一步优化的基础。
    物理查询优化的最终结果是生成最终物理查询执行计划。

    1.5 SQL执行

    在SQL执行阶段,依据物理查询计划执行查询,逐步调用相关算法进行执行。算法包括一趟算法、嵌套循环连接、基于排序的两趟算法、基于散列的两趟算法、基于索引的算法、使用超过两趟的算法等。

    二、 逻辑查询优化

    2.1 逻辑查询优化思路

    查询优化器在逻辑优化阶段主要解决的问题是: 如何找出SQL语句等价的变换形式,使得SQL执行更高效。
    一条SQL查询语句结构复杂,包含多种类型的字句,优化操作依赖于表的一些属性(如索引和约束等)。可用于优化的思路包括:

    • 字句局部优化: 每种类型字句都可能存在优化方式,如等价谓词重写、where和having条件化简中的大部分情况,都属于这种字句范围内的优化。
    • 字句间关联优化: 字句与字句之间关联的语义存在优化的可能,如外连接消除、连接消除、子查询优化、视图重写等都属于字句间的关联优化,因为他们的优化都需要借助其他字句、表定义或列属性等信息进行。
    • 局部与整体的优化: 需要协同考虑局部表达式和整体的关系,如OR重写并集规则需要考虑UNION操作(UNION师变换后的整体的形式)的花费和OR操作(OR是局部表达式)的花费。
    • 形式变化优化: 多个字句存在嵌套,可以通过形式的变化完成优化,如嵌套连接消除。
    • 语义优化:根据完整性约束、SQL表达的含义等信息对语句进行语义优化。

    2.2 查询重写规则

    传统的联机事务处理(OLTP)使用基于选择(SELECT)、投影(PROJECT)、连接(JOIN)3种基本操作相结合的查询,这种查询称为SPJ查询。
    数据库在查询优化的过程中,会对这3种基本操作进行优化。优化的方式如下:

    • 选择操作: 对应的是限制条件(格式类似field consant,field表示列对象,op是操作符,如=,>等),优化方式是选择操作下推,目的是尽量减少连接操作前的远组数,使得中间临时关系尽量少(元组数少,连接得到的远组数就少),这样可减少IO和CPU的消耗,节约内存空间。
    • 投影操作: 对应的SELECT查询的目的列对象,优化方式是投影操作下推,目的是尽量减少连接操作前的列数,使得中间临时关系尽量小(特别注意差别:选择操作是使元组的个数"尽量少",投影操作是使一条元组"尽量小"),这样虽然不能减少IO(多数数据库存储方式是行存储,元组是读取的最基本单位,所以要想操作列则必须读取一行数据),但可以减少连接后中间关系的元组大小,节约内存空间)。
    • 连接关系: 对应的是连接条件(格式类似field_1, field_2,field_1和field_2表示不同表上的列对象,op是操作符,如=,>等),表示两个表连接的条件。这里涉及以下两个子问题:

      • 多表连接中每个表被连接的顺序决定着效率。如果一个查询语句只有一个表,则这样的语句很简单;但如果有多个表,则会涉及表之间以什么样的顺序连接效率最高效(如A、B、C三表连接,如果ABC、ACB、BCA等连接后的结果集一样,则计算哪种连接次序的效率最高,是需要考虑的问题)。
      • 多表连接每个表被连接的顺序由用户语义决定。查询语句多表连接有着不同的语义(如笛卡尔积、内连接 、还是外连接中的左外连接等),这决定着表之间的额前后连接次序是不能随意更换的,否则结果集中数据是不同的。因此,表的前后连接次序是不能随意交换的。
    • 根据SQL语句的形式特点,可以针对SPJ的查询优化,如基于选择、投影、连接3种基本操作相结合的查询。

    2.3 启发式规则再逻辑优化阶段的应用

    逻辑优化阶段使用的启发式规则通常包括如下两类:

    2.3.1 一定能带来优化效果的,主要包括:

    • 优先做选择和投影(选择条件在查询树上下推)
    • 子查询的消除
    • 嵌套连接的消除
    • 外连接的消除
    • 连接的消除
    • 使用等价谓词重写,对条件化简
    • 语义优化
    • 剪掉冗余操作(一些剪枝优化技术)、最小化查询块。

    2.3.2 变换未必会带来性能的提高,需根据代价选择,主要包括:

    • 分组的合并
    • 借用索引优化分组、排序、DISTINCT等操作
    • 对视图的查询变为基于表的查询
    • 连接条件的下推
    • 分组的下推
    • 连接提取公共表达式
    • 谓词的上拉
    • 用连接取代集合操作
    • 用UNIONALL取代OR操作

    三、物理优化

    查询优化器在物理优化阶段,主要解决的问题如下:

    • 从可选的单表扫描方式中,挑选什么样的单表扫描方式是最优的?
    • 对于两个表连接时,如何选择是最优的?
    • 对多个表连接,连接顺序有多种组合,是否要对每种组合都探索?如果不全部探索,怎么找到最优的一种组合?
      在查询优化器实现的早期,使用的是逻辑优化技术,即使用关系代数规则和启发式规则对查询进行优化后,认为生成的执行计划就是最优的。

    在引入了基于代价的查询优化方式后,对查询执行计划做了定量的分析,对每一个可能的执行方式进行评估,挑出代价最小的作为最优的计划。
    目前数据库的查询优化器通常融合这两种方式。

    3.1 查询代价估算

    查询代价估算的重点是代价估算模型,这是物理查询优化的依据。除了代价模型外,选择率对代价求解也起着重要作用。

    3.2 单表扫描算法

    单表扫描需要从表上获取元组,直接关联到物理IO的读取,所以不同的单表扫描方式,有不同的代价。

    3.3 索引

    索引是 建立在表上的,本质上是通过索引直接定位表的物理元组,加快数据获取的方式,所以索引优化的手段应该归属到物理查询优化阶段。

    3.4 两表连接算法

    关系代数的一项重要操作是连接运算,多个表连接是建立在两表之间连接的基础上的。研究两表连接的方式,对连接效率的提高有着直接的影响。

    3.5 多表连接算法

    多表连接算法实现的是在查询路径生成的过程中,根据代价估算,从各种可能的候选路径中找出最优的路径(最优路径是代价最小的路径)。
    多表连接算法需要解决两个问题:

    • 多表连接的顺序: 表的不同连接顺序,会产生许多不同的连接路径;不同的连接路径有不同的效率。
    • 多表连接的搜索空间:因为多表连接的顺序不同,产生的连接组合会有多种,如果这个组合的数据巨大,连接次数会达到一个很高的数量级,最大可能的连接次数是N!(N的阶乘)。比如N=5,连接次数是120;N=10,连接次数是362880。所有的连接可能构成一个巨大的"搜索空间"。如何将搜索空间限制在一个可接受的时间范围内,并高效地生成查询执行计划将成为一个难点。

    四、查询优化器与其他模块的关系

    在数据库内部,根据功能不同,可以划分出多个模块,不同模块之间有的关系紧密,有的关系松散。查询优化器是其中的一个功能模块,是实现查询优化技术的模块。下面介绍数据库中与查询优化器相关的模块:

    4.1 查询优化器与语法分析器

    语法分析器是查询优化器的输入。理解查询优化器,从语法分析器开始,将是个好的开端。因为不同对象有着不同的数据结构,数据结构成员是对象属性的载体,而语法分析器把一个SQL分解为众多数据结构体并给数据结构赋值,这样才能被查询优化器逐项获取并用与计算,比如逻辑查询优化有一条"常量传递"规则,如果没有语法分析器分解条件,也不可能推知列值是常量,也不可能有此优化。

    4.2 优化器与执行器

    查询优化器是执行器的前端输入部分。查询优化器计划一条SQL的具体执行方式和步骤 ,执行器具体去完成计划中的每一步。
    在实践中,一条SQL最耗时的阶段多发生在执行阶段。如果查询计划做得不好,则执行起来非常耗时。

    4.3 优化器与缓冲区

    缓冲区有多种多样,比如与数据相关的缓冲区(如从存储设备加载数据到内存)、与实现过程相关的辅助缓冲区(如排序用到的临时表或内存块),与功能模块相关的缓冲区(如日志缓冲区)等。
    优化器主要是对SQL输入进行逻辑方式的变换,没有涉及数据部分,只涉及对数据量的估计。当估算排序空间的时候,会涉及排序缓冲区;当估算数据IO的时候,需要考虑数据是否在数据缓存中。所以,查询优化器与数据缓冲区有一定的关系。

    4.4 优化器与统计

    MySQL数据库的查询优化器使用了基于代价的查询执行计划估算,所以依赖于被查对象的各种数据,而数据是动态变化的,如表的元组数。如果实时获取这些数据,系统计算的开销会比较大。为了避免这样的问题,定期或者根据需要统计这些数据,则比较切合实际。
    优化器在物理优化阶段,需要对单表读取开销,两表连接开销,多表连接顺序开销等进行比较,比较基于的就是一些基础数据的值,这些数据通常不会被实时更新,所以优化器有时做出的计划未必是最合适的。

    4.5 优化器与索引

    优化器做物理查询优化需要利用索引提高单表扫描效率,进而减少了多表连接时的元组数,所以确定哪些索引可用、怎么有效利用索引等都在查询优化器中得到体现。

    五、 MySQL查询优化器概述

    MySQL 查询优化器的主要功能是完成SELECT语句的执行,在保证SELECT语句正确执行之外,还有一个重要的功能,就是使用关系代数、启发式规则、代价估值模型等不同种类的技术,提高SELECT语句的执行效率。

    MySQL 查询 优化 器 实现 第 2 章介绍 的 大多数查询优化技术,这些 技术, 用于 对 SPJ 和 非 SPJ 类型 的 查询 语句 进行 优化。

    下面将从整体上介绍MySQL查询优化器, 分别对MySQL 查询优化器的执行过程、架构、层次、设计 思想、主要概念、代码结构上宏观探讨MySQL查询优化器的实现。

    5.1 MySQL查询执行过程

    MySQL查询执行过程分为4个阶段,如下所示:

    • 语法分析阶段: 将SQL查询语句经词法和语法分析后变换成为一棵查询树st_select_lex传给优化器,并对SQL表达的语义进行检查。
    • 生成逻辑查询执行计划阶段: 优化器在查询树中遍历每个关系,确定关系是否是常量表、为每个关系查找可用的索引、运用关系代数原理和启发式规则进行逻辑上的查询优化(如消除子查询、消除外连接等)。
    • 生成物理查询执行计划阶段: 优化器对各个连接的表进行排序,然后求解多表连接最优路径,对于每个关系尽量利用索引计算其代价,找出代价最小的路径后保存到JOIN类的bets_positions
    • 执行查询执行计划阶段: 把查询执行计划传到执行器进行执行。

    mysql-exe.png

    MySQL查询优化器在逻辑查询执行计划阶段,机遇关系代数规则和启发式规则,把用户指定的SQL经过"等价"的代数转换,变为一种更节省IO的执行序列,执行起来更为高效。

    MySQL查询优化器在物理查询执行计划阶段,在解决多表连接的问题时,有两套算法:一是用户指定表连接次序的算法;二是混杂了贪婪和穷举思想的算法,解决的是较多表的连接和非用户指定连接次序的多表连接,但不能保证得到最优的查询执行计划。

    5.2 MySQL查询优化器的架构和设计思想

    MySQL查询优化器设计精巧,但层次不够清晰,V5.6之后的版本,混乱状态有所改善,但MySQL查询优化器实用而高效,在充分利用索引的基础上,实现了很多查询优化技术,有很多精巧之处值得学习探索。

    MySQL查询优化过程中,查询优化器通过JOIN对象的方法,如JOIN.prepare()、JOIN.optimize(),完成优化工作。JOIN.prepare()完成的查询优化主要包括:子查询的冗余子句消除、IN类型子查询优化、将ALL/ANY等类型的子查询转换为MIN/MAX等操作,这是对简单子查询进行的优化;JOIN.optimize()函数完成的查询优化主要包括:子查询上拉,把外连接优>化为内连接,把嵌套连接消除,WHRER子句、JOIN/ON子句、HAVING子句条件表达式的化简(尤其是对含有常量的表达式的化简、等式合并),优化没有GROUPBY子句情况下的COUNT(*)、MIN()、MAX(),裁剪分区partition(如果查询的表是分区表),确定多表的连接路径(单表是多表的特例,统计join的代价,两种多表连接算法选其一搜索最优的join顺序、生成执行计划)、优化等式谓词、优化DISTINCT、创建临时表存储临时结果优化分组排序等操作。在这样的过程中,MySQL没有把优化过程明显地分为逻辑查询优化阶段和物理查询优化阶段,而是互为混杂,在物理查询优化之后,继续进行了部分逻辑查询优化。这是MySQL查询优化器的一大特点。

    5.3 MySQL查询优化器架构

    MySQL查询优化器为SQL查询语句求解最优的执行方式。MySQL查询优化器架构和执行过程如下图所示。

    MySQL-opimize-structure.png

    MSQL查询语句的执行主要历经4个过程,分别如下:

    1. P1过程:SQL语句输入变为语法查询树。
    2. P2过程:查询预处理,优化相关的内容主要是子查询优化。
    3. P3过程:语法树变为逻辑关系查询树,进而变为物理查询执行计划,挑出最优计划。
    4. P4过程:依据最优查询执行计划得到查询结果。

    MySQL查询语句的执行,主要历经以下4个模块。

    1. M1模块:语法分析模块,执行过程P1的任务。
    2. M2模块:查询 预处理模块,执行过程P2的任务。
    3. M3模块:查询优化模块,执行过程P3的任务。
    4. M4模块:查询执行模块,执行过程P4的任务。

    实现MySQL查询优化器功能的主要是M3模块,其主要有以下两个子阶段的工作。

    • M3-S1逻辑查询优化阶段:把语法查询树通过关系代数原理,优化为关系代数查询树,关系代数的原理在这个阶段运用;
    • M3-S2物理查询优化阶段:把关系代数查询树用于贪婪算法,生成最优执行计划。

    5.4 MySQL查询优化器的层次

    MySQL整个查询优化器从代码层面看,逻辑结构不是很清晰,但是从技术层面看,还是能够分为两个阶段,一是逻辑查询优化阶段,二是物理查询优化阶段。

    • 逻辑查询优化阶段主要依据关系代数可以推知的规则和启发式规则,对SQL语句进行等价变换。MySQL淋漓尽致地使用了关系代数中可推定的各项规则,对投影、选择等操作进行句式的优化;对条件表达式进行了谓词的优化、条件化简;对连接语义进行了外连接、嵌套连接的优化;对集合、GROUPBY等尽量利用索引、排序算法进行优化。另外还利用子查询优化、视图重写、语义优化等技术对查询语句进行了优化。
    • 在物理查询优化阶段,通过贪婪算法,并依据代价估算模型,在求解多表连接顺序的过程中,对多个连接的表进行排序并探索连接方式,找出花费最小的路径,据此生成查询执行计划。在这个阶段,对于单表扫描和两表连接的操作,高效地使用了索引,提高了查询语句的执行速度。

    六 、 从功能角度看MySQL查询优化

    MySQL的查询优化技术的实现,基本也可以分为逻辑优化和物理优化两个阶段,只是和PostgreSQL相比,界线没有那么清晰。MySQL的查询优化过程概述如下:

    1. 优先处理集合操作,把集合操作分解为普通的SPJ和非SPJ操作。
    2. 应用子查询优化技术,去除子查询中冗余部分,转换为半连接、用物化操作优化子查询、执行In向EXISTS转换、优化ALL/ANY等类型的子查询向MIN/MAX转换等。
    3. 消除外连接、消除嵌套连接。
    4. 利用等价谓词重写优化技术,优化WHERE、JOIN/ON、 HAVING等条件中的表达式,尤其是常量表达式和多重等式。
    5. 利用索引优化count(*),MIN(),MAX()。
    6. 进行多表连接的顺序确定。

      • 找出常量表,求解多表连接的过程中不使用常量表作为连接的表(减少搜索空间)。
      • 尽量利用索引优化GROUP BY、DISTINCT结合的操作
      • 利用代价估算模型,评估连接的花费,找出最优连接。
      • 用物化优化半连接嵌套的形式。
      • 从两种多表连接的算法中任选其一: 一是用户指定连接顺序 ,二是使用贪婪和穷尽结合的方式。
      • "选择"、"投影"操作下推
      • 利用索引对ORDER BY进行优化
      • 对GROUP BY/DISTINCT的组合情况进行优化
      • 确定半连接优化策略,从5种备选策略选择其中之一。
      • 对没有GROUP BY和ORDER BY字句的IN子查询进行优化。

    七、 参考文献

    书籍: <<数据库查询优化的艺术: 原理解析和SQL性能优化>>

    展开全文
  • MySQL 查询优化

    千次阅读 2021-01-27 12:09:13
    使用索引规则全值匹配:查询的字段按照顺序在索引中都可以匹配到,最佳左前缀法则:指的过滤条件要使用索引必须按照索引建立时的顺序依次满足 , 一旦跳过某个字段 , 索引后面的字段都无法被使用。不在索引列上做...

    使用索引

    规则

    全值匹配:查询的字段按照顺序在索引中都可以匹配到,

    最佳左前缀法则:指的过滤条件要使用索引必须按照索引建立时的顺序依次满足 , 一旦跳过某个字段 , 索引后面的字段都无法被使用。

    不在索引列上做计算:不在索引列上做任何操作(计算、函数、(自动 or 手动)类型转换「尤其注意 varchar 和 int」),会导致索引失效而转向全表扫描。

    索引列上不能有范围查询:将可能做范围查询的字段的索引顺序放在最后

    尽量使用覆盖索引:查询列和索引列一致,不写 select *;

    不使用不等于(!=以及 <>)

    当字段允许为 NULL 时:where 后条件 is null 可以使用索引,is not null 不可以用到索引

    Like 以通配符(%sadfj%)开头时,MySQL 索引失效。解决办法:①可以使用主键索引;②使用覆盖索引,查询字段必须是建立覆盖索引字段;③当覆盖索引指向的字段是 varchar(380) 及 380 以上的字段时,覆盖索引会失效!

    字符串不加单引号索引失效

    少用 or,用了索引会失效

    示例

    236256826dda1b16b23ee74b611d534b.png

    助记口诀

    全职匹配我最爱,最左前缀要遵守;

    带头大哥不能死,中间兄弟不能断;

    索引列上少计算,范围之后全失效;

    LIKE 百分写最右,覆盖索引不写*;

    不等空值还有 OR,索引失效要注意;

    VAR 引号不可丢,SQL 优化有诀窍。

    具体方案

    关联查询优化

    LEFT JOIN:左侧为驱动表,右侧为被驱动表

    INNER JOIN:MySQL 会自动将小结果的表作为驱动表

    straight_join:效果和 inner join 一样,但是会强制将左侧作为驱动表!

    子查询尽量不要放在被驱动表,有可能使用不到索引,会生成临时表。

    在优化关联查询时,在被驱动表建立索引才有效。

    排序优化

    在索引列上

    ORDER BY 语句使用索引最左前列

    使用 WHERE 子句与 ORDER BY 子句条件列组合满足索引最左前列

    ORDER BY 后字段同时使用升序或降序

    如果 WHERE 使用索引的最左前缀为常量,则 OEDER BY 可以使用索引

    ad7086e2c983cec5a60f57ca9c3cc80b.png

    不在索引列上

    双路排序:字面意思就是两次扫描磁盘,最终得到数据,读取行指针和orderby列,对他们进行排序,然后扫描已经排序好的列表,按照列表中的值重新从列表中读取对应的数据输出。

    单路排序:从磁盘读取查询需要的所有列,按照order by列在buffer对它们进行排序,然后扫描排序后的列表进行输出,它的效率更快一些,避免了第二次读取数据。并且把随机IO变成了顺序IO,但是它会使用更多的空间,因为它把每一行都保存在内存中了。效率高

    单路容易出现的问题:如果取出的数据总大小超过了 sort_buffer 的容量,导致每次只能取sort_buffer容量大小的数据,进行排序(创建tmp文件,多路合并),排完再取取sort_buffer容量大小,再排……从而多次I/O。

    优化策略

    ① 增大 sort_buffer_size参数的设置(单路排序的内存大小)

    ② 增大 max_length_for_sort_data参数的设置(单次排序字段大小)

    ③ 去掉select 后面不需要的字段

    分组优化

    同 排序优化

    实质是先排序后分组,遵循索引最左前缀

    当无法使用索引列,增大max_length_for_sort_data参数的设置+增大sort_buffer_size参数的设置

    WHERE 效率高于 HAVING

    子查询优化

    有索引:inner join 是最好的,其次是 in,exists 最糟糕

    无索引:反之(待验证)

    分页优化

    优化前:EXPLAIN SELECT SQL_NO_CACHE * FROM emp ORDER BY deptno LIMIT 10000,40;会出现 using filesort

    c5cf360b08ca7604ade4e134b79bf1dd.png

    加索引后没效果:

    b8dcad3ba9ca98040c7ba0eb187e4c3d.png

    优化后:EXPLAIN SELECT SQL_NO_CACHE * FROM emp INNER JOIN (SELECT id FROM emp e ORDER BY deptno LIMIT 10000,40) a ON a.id=emp.id

    7e5b85e151d9b521f3616f1fe6a7eeb9.png

    优化思路: 先利用覆盖索引把要取的数据行的主键取到,然后再用这个主键列与数据表做关联(查询的数据量小了后再进行查询)。

    去重查询

    尽量不要使用 distinct 关键字去重,可以使用 group by+需要去重的字段,这个时候会用到索引

    对于 IN 和 EXISTS 的使用

    直接说个结论吧:EXISTS 后接大表,IN 后接小表,两表大小无差别两者都行

    关联阅读

    MySQL Explain 使用,看这一篇就够了

    MySQL 查询语句执行过程

    数据库优化指南

    MySQL 索引入门

    展开全文
  • MySQL查询优化器工作原理解析

    万次阅读 2016-05-28 21:06:31
    手册上MYSQL查询优化器概述;个人对MySQL优化器的理解;分析优化器优化过程中的信息;调节MySQL优化器的优化等
  • mysql查询优化

    千次阅读 2019-03-15 00:55:44
    优化器分类 传统关系型数据库里面的优化器分为CBO和RBO两种。 RBO— Rule_Based Potimizer 基于规则的优化器: RBO :RBO所用的判断规则是一组内置的规则,这些规则是硬编码在数据库的编码中的,RBO会根据这些规则...
  • 主要介绍了Mysql根据时间查询日期的优化技巧,非常不错,具有参考借鉴价值,需要的朋友可以参考下
  • mysql分页查询优化

    千次阅读 2021-02-02 05:39:43
    直接用limitstart,count分页语句,也是我程序中用的方法:select * from product limit start, count当起始页较小时,查询没有性能问题,我们分别看下从10,100,1000,10000开始分页的执行时间(每页取20条),如下...
  • MySQL查询优化:GROUP BY

    万次阅读 多人点赞 2019-03-05 19:46:16
    group by 优化方法 — 索引 松散索引扫描(Loose Index Scan) 为什么松散索引扫描的效率会很高? 紧凑索引扫描(Tight Index Scan) group by 优化方法 — 直接排序 二、group by 与 distinct 三、排序不一致...
  • 本文介绍主要介绍在mysql中使用in语句时,查询效率非常慢,这里分享下我的解决方法,供朋友们参考。
  • MySQL-查询优化

    万次阅读 多人点赞 2018-12-20 18:32:02
    对于刚入行的程序猿来说,如何优化MySQL查询,是必须跨过的坎。网上有很多关于SQL优化的博文,但大多是片段和结论。这里,我摘抄了《高性能MySQL》一书的内容,从全局的角度将MySQL查询优化的思路和要点进行串通,...
  • mysql优化(关联查询优化)

    千次阅读 2022-03-12 22:07:58
    1.准备数据 #分类 CREATE TABLE IF NOT EXISTS `class` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `card`... - 子查询尽量不要放在被驱动表,衍生表建不了索引 - 能够直接多表关联的尽量直接关联,不用子查询
  • MySQL查询优化之一-WHERE语句优化

    千次阅读 2018-01-18 13:51:34
    MySQL查询优化之一-WHERE语句优化 如需转载请标明出处:http://blog.csdn.net/itas109 QQ技术交流群:12951803 环境: MySQL版本:5.5.15 操作系统:windows 本文讨论WHERE语句的优化。 这些示例使用SELECT...
  • MySQL查询优化之二-范围优化(Range Optimization) 如需转载请标明出处:http://blog.csdn.net/itas109 QQ技术交流群:12951803 环境: MySQL版本:5.5.15 操作系统:windows 本文讨论范围的优化...
  • Mysql百万级以上查询优化总结,,对mysql优化、索引优化
  • 常见Mysql的慢查询优化方式

    万次阅读 多人点赞 2018-09-21 16:37:02
    这篇文章主要是就在公司实习的时候,对SQL优化工作作出的一些整理。  在公司实习的时候,导师分配了SQL慢查询优化的任务,任务是这样的:每周从平台中导出生产数据库的慢查询文件进行...开启mysql查询   方...
  • MySQL调优(五):MySQL查询优化分析

    万次阅读 2020-06-27 01:38:53
    思考:下面这个limit怎么通过子查询进行优化? 避免: 1、避免查询不需要的记录 我们常常会误以为mysql会只返回需要的数据,实际上mysql却是先返回全部结果再进行计算,在日常的开发习惯中,经常是先用select语句查
  • mysql 大数据性能优化
  • 简单介绍了一些常见MySQL数据库优化手段,比如减少数据访问、使用索引、使用关联查询等等。
  • 最近,发现业务线程卡死在读取数据库(MySQL 5.7),数据库CPU飙升到了100%,经过定位发现是下面这样一个SQL(由用户触发的查询,可以理解为查看这个群组的所有用户买过哪些商品)导致的: select * from ...
  • MySQL查询优化查询优化

    千次阅读 2009-08-20 16:45:00
    MySQL查询优化查询优化器phpma.com  当你提交一个查询的时候,MySQL会分析它,看是否可以做一些优化使处理该查询的速度更快。这一部分将介绍查询优化器是如何工作的。如果你想知道MySQL采用的优化手段,可以查看...
  • MySQL查询优化之十-ORDER BY优化(ORDER BY Optimization) 如需转载请标明出处:http://blog.csdn.net/itas109 QQ技术交流群:12951803 环境: MySQL版本:5.5.15 操作系统:windows 本文讨论ORDER BY优化...
  • MySQL查询优化之九-IS NULL优化(IS NULL Optimization) 如需转载请标明出处:http://blog.csdn.net/itas109 QQ技术交流群:12951803 环境: MySQL版本:5.5.15 操作系统:windows 本文讨论IS NULL优化(IS ...
  • MySQL排序查询优化

    千次阅读 2018-12-13 17:17:47
    两张表连接查询并limit,SQL效率很高,但是加上order by以后,语句的执行时间变的巨长,效率巨低,接下来为大家介绍下连接查询排序limit 不知道有没有人碰到过这样恶心的问题:两张表连接查询并limit,SQL效率很高...
  • mysql查询优化需要注意的20点

    万次阅读 2014-02-11 16:40:43
    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显。...这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库。希望下面的这些优化技巧对你有用。 1. 为
  • MySQL查询优化之COUNT()

    千次阅读 2015-08-02 17:14:58
    COUNT()聚合函数,以及如何优化使用了该函数的查询,很可能是MySQL中最容易被误解的前10个话题之一,在网上随便搜索一下就能看到很多错误的理解,可能比我们想象的多得多。在做优化之前,先来看看COUNT()函数的真正...
  • Mysql查询时间优化

    千次阅读 2021-01-18 21:17:18
    ------------------------------------------- 之前说过MySQL的时间字段有date,time,datetime,timestamp等,在实际查询时间段时,我们经常将整个字段存储进去,例如像2011-03-10 00:00:00,也有分开存储年,月,日的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 477,706
精华内容 191,082
关键字:

mysql查询优化

mysql 订阅