MySQL-学习

1.Percona Server和MariaDB是MySQL的完全可替代版本;MySQL能运行于现今流行的各大平台:Mac、Windows、Linux等
2.MySQL服务器逻辑架构图:存储引擎不会去解析SQL(InnoDb例外,会解析外键定义,因为MySQL服务器本身没有实现该功能),不同引擎之间也不会相互通信,只是简单的响应上层服务器请求。
    
3.共享锁(shared lock->读锁):共享,相互不阻塞,多个客户在同一时刻可同时读取同一资源,互不干扰
   排他锁(exclusive lock->写锁):一个写锁会阻塞其他的写锁和读锁
4.表锁(table lock):MySQL最基本的锁策略,且开销最小
   行级锁(row lock):可最大支持并发处理(同时也带来了最大的开销),InnoDB和XtraDB
5.事务:ACID
    原子性(atomic):一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要买全部失败回滚。
    一致性(consistency):数据库总是从一个一致性的状态转换到另一个一致性的状态。
    隔离性(isolation):一个事务所做的修改在最终提交以前,对其他事务是不可见的
    持久性(durability):一旦事务提交,则其所做的修改就会永久保存到数据库中
6.隔离级别:SET ISOLATION LEVEL完成修改,新的隔离级别会在下一个事务开始时生效
   未提交读(READ UNCOMMITED):事务中的修改,即使没有提交,对其他事务也都是可见的
   提交读(READ COMMITED-->不可重复读): 大多数数据库系统的默认隔离级别;一个事务从开始直到提交之前,所做的任何修改对其他事务
都是不可见的,因为执行两次同样的查询,可能会得到不一样的结果
    可重复读(REPEATABLE READ): MySQL的默认隔离级别,在同一个事务中多次读取同样记录的结果是一致的,解决了脏读的问题,但无法解决幻读问题:当事务A在读取某个范围内的记录时,事务B又在该范围内插入了新的记录,事务A再次读取该范围的记录时,会产生幻行;InnoDB和XtraDB引擎通过多版本并发控制(MVCC)解决了幻读问题
    可串行化(SERIALIZABLE):最高的隔离级别,通过强制事务串行执行,避免了幻读的问题。极少用,只有当非常需要一致性且无并发要求才考虑使用
7.死锁:两个或多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。InnoDB检测到死锁的循环依赖,则立即返回错误,将最少行级排他锁的事务进行回滚
8.MySQL事务:默认采用自动提交(AUTOCOMMIT),如果不显式地开始一个事务,则每个事务都被当做一个事务执行提交操作。
  SHOW VARIABLES LIKE 'AUTOCOMMIT' 查看提交模式;SET AUTOCOMMIT=0 完成关闭
  另外对于非事务的表,比如MyISAM或者内存表不会有任何影响,因为没有COMMIT或ROLLBACK概念
   InnoDB是两段锁协议,锁只有在COMMIT或ROLLBACK时才会释放,且所有锁是在同一时刻被释放
    除了事务中已禁用AUTOCOMMIT可以使用LOCK TABLES外,其他任何使用都不要显示地执行LOCK TABLES,不管什么引擎。
9.InnoDB(支持在线热备份)针对MVCC:
    1.Select只查找版本早于当前事务版本的数据行;行的删除版本要么未定义,要么大于当前事务版本号,这可确保事务读取到的行,在事务开启前未被删除
    2.Insert:新插入的每一行保存当前系统版本号作为行版本号
    3.Delete:删除的每一行保存当前系统版本号作为行删除标识
    4.Update:为新记录保存当前系统版本号作为行版本号,同时保存当前系统版本号作为行删除标识
    MVCC只在可重复读和提交读两个隔离级别下工作
10.MySQL的InnoDB引擎将每个数据库(schema)保存为数据目录下的一个子目录,创建表时会在子目录下创建一个和表同名的.frm文件保存表的定义; 数据存储在表空间(tablespace)
     
11.MyISAM引擎不支持事务、蹦溃后的安全恢复;对于只读的数据或表比较小,可以忍受修复操作,则可继续使用(不建议默认MyISAM,而应当是InnoDB)
    MyISAM将表存储在数据文件(.MYD)和索引文件(.MYI);表可包含动态或静态(长度固定)行;5.0版本中如果是变长行,默认配置只能处理256TB数据
    对整张表加锁,而不是针对行;对读取的所有表加共享锁,写入时加排他锁;但表有读取查询的同时,也可插入新记录(并发插入)
    可通过CEHCK TABLE mytable检查表的错误,REPAIR TABLE mytable进行表修复;如果MySQL已关闭,可通过myisamchk进行检查和修复
    对于MyISAM表,即使是BLOB和TEXT等的长字段,也可基于前500个字符创建索引,支持全文索引
    延迟更新索引键(全局或单表设置):创建表时如果指定了DELAY_KEY_WRITE则在每次修改完成时,不会立刻将修改的索引数据写入磁盘,而是写到内存缓冲区,只有在清理键缓冲区或关闭表时才会将对应的索引块写入磁盘;提高了性能,但在数据库或主机崩溃时或造成索引损坏,需执行修复操作。
12.压缩表:表在创建并导入数据后,不会再进行修改操作,则可使用myisampack对表进行压缩,仍支持索引,但只能读
13.如何选择合适的引擎:除非需要用到InnoDB不具备的特性,且无其他办法可替代,否则都应优先选择InnoDB引擎;不建议混合使用多种引擎
    要用到全文索引:建议InnoDB+Sphinx的组合而不是使用支持全文索引的MyISAM
    用MyISAM:不在乎扩展、并发和崩溃后数据丢失问题,对InnoDB的占用空间多比较敏感;
    选择引擎考虑点:事务、备份、崩溃恢复、特有特性
    日志型应用插入速度快,数据库不能成为瓶颈,可考虑MyISAM或Archive
    订单类的应用,InnoDB是最佳选择
14.修改引擎:alter table mytable  engine=InnoDB;如果转换表的存储引擎,将会失去和原引擎相关的所有特性;
    可使用mysqldump将数据导出到文件,再修改CREATE TABLE的存储引擎,同时修改表名,并注意DROP TABLE语句
    或采用先创建一个新的存储引擎表,再通过INSERT...SELECT来导数据
    create table innodb_table like myisam_table;
    alter table innodb_table engine=InnoDB;
    insert into innodb_table select *  from myisam_table;如果数据量多,则分批次按小事务导入
二.基准测试
    1.基准测试要尽量简单直接,结果之间容易相互比较,成本低且易于执行
    2.策略:集成式:针对整个系统的整体测试
                  单组件式:单独测试MySQL
    3.测试目标:
     a.吞吐量:单位时间内的事务处理数
     b.响应时间或延迟:用于测试任务所需的整体时间
     c.并发性:正在工作中的并发操作或同事工作中的线程数或连接数
     d.可扩展性:给系统增加一倍的工作,在理想的情况下就能获得两倍的结果
    4.集成式测试工具:
     a.ab是一个Apache HTPP服务器基准测试工具,测试HTTP服务器每秒最多可处理多少请求
     b.http_load:通过一个输入文件提供多个URL,进行随机选择URL进行测试
        http_load -parallel 5 -seconds 10 url.txt
     c.JMeter:可加载其他应用并测试其性能
     5.单组件式测试工具:
      1.mysqlslap:可模拟服务器的负载,并输出计时信息,测试时可执行并发连接数,并指定SQL;如果无SQL语句,会自动生成查询schema的SELECT语句
       2.sql-bench:单线程,用于测试不同数据库服务器执行查询的速度;缺点:单用户模式,测试的数据集小且无法使用指定的数据,同个测试多次运行的结果可能会相差很大
       3.Super Smack:用于MySQL和PostgreSQL,可进行压力测试和负载生成;可模拟多用户访问,加载测试数据到数据库,并支持随机数据填充测试表
       4.sysbench:多线程系统压测工具,可根据影响数据库服务器性能的各种因素来评估系统的性能,支持Lua
       5.MySQL内置BENCHMARK(),可测试某些特定操作的执行速度
          
三.服务器性能:
    1.性能:为完成某件任务所需要的时间度量
       性能剖析:测量和分析时间花费在哪些步骤--->New Rlelic软件支持web,会插入到代码进行性能剖析
        a.测量任务所花费时间,然后对结果进行统计和排序,将重要的任务排到前面
     2.优化:先检查时间花在了哪些步骤,找出合适的测试范围,才能对症下药
        不需优化的情况:
        a.只占总响应时间比重很小的查询            b.优化的成本大于收益
     3.慢查询日志:开销最低、精度最高的测量查询时的工具,通过long_query_time(Percona Server功能更强pt-query-digest)为0来捕获所有查询;如果要长期开启慢查询日志,注意要部署日志轮转(log rotation)工具
     4.SHOW PROFILE:默认禁用,通过SET profiling=1;开启
       show PROFILE for query 1;   给出查询执行的每个步骤及其花费时间
      
    5.show status;返回服务器级别的全局计数器(句柄计数器handler counter、临时文件和表计数器),也有某个连接的会话级别计数器;
` ``6.explain也可得到类似show status的结果,不过是估计得到的结果,而show status是实际的测量结果
     7.show GLOBAL STATUS;  可检查Threads_running、Threads_connected、Questions和Queries等来查慢问题
     8.show PROCESSLIST; 可观察是否有大量线程处于不正常的状态或其他不正常的特征
四、Schema与数据类型优化
     1.更小的通常更好:应尽量选择可正确存储数据的最小数据类型
        简单就好:简单数据类型的操作通常需要更少的cpu周期
        尽量避免NULL:默认为NULL,除非真的需要存储NULL值,否则建议指定为NOT NULL
        datetime和timestamp都可存储相同类型的数据,精确到秒;但timestamp只使用datetime一半的存储空间;缺点允许的时间范围小得多,有时会成为障碍
    2.数据类型:
      a.整数类型:TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT分别使用8、16、24、32、64位;UNSIGNED可使正数的上限提升一倍,有符号和无符号使用相同的存储空间和具有相同的性能;对于INT(1)和INT(20)而言,存储和计算是相同的,只是规定了MySQL的一些交互工具用于显示的字符个数。
      b.实数类型:DECIMAL用于存储精确小数,支持精确计算,可指定小数点前后允许的最大位数,但会影响列的空间消耗,尽量在只对小数进行精确计算时才用(如财务数据);FLOAT占4字节,DOUBLE占8字节
      c.字符串类型:
        VARCHAR:用于存储可变长字符串,更节省空间;如果MySQL表使用ROW_FORMAT=FIXED创建,则每一行都会使用定长存储,浪费空间;使用场景:字符串列的最大长度比平均长度大很多;列的更新很少;使用UTF-8等字符集每个字符都使用不同的字节数进行存储。
        CHAR:定长,总是根据定义的长度分配足够的空间,存储时会删除所有末尾空格;适合存储很短的字符串或所有值都接近同一个长度,例如:存储密码的MD5值;经常变更的数据,会比VARCHAR更好,不容易产生碎片;对于非常短的列,在存储空间上比VARCHAR更有效率。
        BINARY和VARBINARY存储的是二进制字符串(字节码),大小写敏感
    d.BLOB(二进制数据,无排序规则或字符集)和TEXT(有字符集和排序规则)类型:可存储很大的数据,分别采用二进制和字符方式存储。当值过大时,InnoDB会用"外部"存储区域来存储,此时每个值在行内需1~4个字节存储一个指针,然后在外部存储区域存储实际的值。
        只对每个列的最前max_sort_length字节而非全部字符串做排序,不需要过多字符排序,可减少max_sort_length配置或ORDER BY SUBSTRING(column,length)
        TINYTEXT SMALLTEXT TEXT MEDIUMTEXT LONGTEXT
        TINYBLOB SMALLBLOB BLOB MEDIUMBLOB LONGBLOB
        EXPLAIN执行计划的Extra列包含“Using temporary”,则说明查询使用了隐式临时表
    e.枚举(ENUM)
       枚举列可把一些不重复的字符串存储成一个预定义的集合,存储时会根据列表值的数量压缩到一个或两个字节中;实际存储、排序(可通过FIELD()显式指定排序顺序,但会导致MySQL无法利用索引消除排序)为数字,而不是字符串;枚举缺点:字符串列表是固定的,添加或删除字符串必须使用ALTER TABLE
     f.日期和时间类型:
       DATETIME能保存大范围的值,从1001到9999年,精度为秒,与时区无关,8字节的存储空间。
       TIMESTAMP存储1970.1.1到2038年的秒数和UNIX时间戳相同,展示依赖时区,4字节的存储空间;FROM_UNIXTIME()将unix时间戳转日期;UNIX_TIMESTAMP()将日期转Unix时间戳
        除特殊行为外,尽量用TIMESTAMP,因为空间效率更高;经常使用show create table 表名    检查表
      g.位数据类型: bit列最大是64位,bit(1)存储1位。MySQL把bit当做字符串而非数字类型;存储b‘00111001’  用select a,a+0 from 表名  得到a=9  a+0=57;  所以对于大部分应用,尽量避免使用bit;如果想存储true/false值,可用char(0)代替
       h.选择表示符(identifier):整数通常是标识列最好的选择,访问速度快且可使用AUTO_INCREMENT;也可使用ENUM和SET;尽量避免字符串类型,因为消耗空间。 存储UUID时应移除"-"符号或用UNHEX()函数转换,并存储在BINARY(16)列中,检索时用HEX()再格式化
       i.特殊类型数据:IPv4建议用无符号整数存储IP地址,转换时用INET_ATON()和INET_NTOA()
    3.Schema设计陷阱:
       a.MySQL限制了每个关联操作最多只能有61张表,建议:希望查询执行快且并发性好,单个查询在12个表以内做关联。
       b.防止过度使用枚举;MySQL会在索引中存储NULL值,而Oracle则不会
    4.范式和反范式:
      a.在范式化的数据库中,每个事实数据会出现且只出现一次
      b.范式化的优点和缺点:
         优点:更新操作通常比反范式化要快;当数据较好地范式化时,就只有很少或没有重复数据,需修改更少的数据;
                    范式化的表通常更小,可更好地放内存里,执行会更快;更少需要用distinc或group by
         缺点:通常需要关联
      c.反范式化优缺点:常见场景:复制或缓存,在不同表中存储相同的特定列
        1.数据都在一张表中,可避免关联;最差查询即没有使用到索引,全表扫描(基本是顺序I/O,但也不是100%,跟引擎有关)
      d.缓存表:存储那些可比较简单地从schema其他表获取(每次速度慢)数据的表(例如逻辑上冗余的数据);对优化搜索和检索查询语句很有效。
                     如果需要不同的索引组合来加速查询,可考虑对缓存表使用不同的存储引擎(如MyISAM更小的索引占用空间和可做全文搜索)
         汇总表:保存使用GROUP BY语句聚合数据的表(例如数据不是逻辑上冗余的)
       e.快速创建MyISAM索引:为了搞笑载入数据到MyISAM表,常用方法:先禁用索引,载入数据,然后重新启用索引:
          alter table test.table disable keys---->alter table test.table enable keys;此方法只对非唯一索引有效,因为MyISAM会在内存中构造唯一索引,并且为载入的每一行检查唯一性,一旦索引的大小超过了内存大小,载入操作就会变得越来越慢。
        REPAIR TABLE用于重建表的索引,会通过排序来构建所有索引,包括唯一索引
五、创建高性能索引:索引适合于中到大型的表
    1.索引优化应该是对查询性能优化最有效的手段;MySQL只能高效地使用索引的最左前缀列;ORM也是只能支持最普通查询
    2.B-Tree索引:大多数MySQL引擎都支持这种索引,Archive引擎例外;InnoDB采用B+Tree,按原数据格式存储索引,根据主键引用被索引的行。
       B-Tree:加快访问数据速度,因为存储引擎不再需要进行全表扫描来获取需要的数据,而是从索引的根节点开始进行搜索;对索引列顺序组织存储,适合查找范围数据
       优点:1.大大减少了服务器需要扫描的数据量
                  2.可帮助服务器避免排序和临时表
                  3.可将随机I/O变为顺序I/O
       B-Tree适用于全键值、键值范围或键前缀查找(最左前缀查找);限制:如果不是按照索引的最左列开始查找,则无法使用索引;
不能跳过索引中的列(不指定则MySQL只能使用索引的第一列);如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找
       全值匹配:和索引中的所有列进行匹配
       匹配最左前缀:只使用索引的第一列
       匹配列前缀:只匹配某一列的值的开头部分
       匹配范围值:查找某个范围里的数据
       精确匹配某一列并范围匹配另外一列:如第一列全匹配,第二列范围匹配
       只访问索引的查询:查询只需要访问索引,而无需访问数据行
    3.哈希索引:基于哈希表实现,只有精确匹配索引所有列的查询才有效,目前只有Memory显示支持(默认的索引类型)、   
    4.空间数据索引(R-TREE):支持空间索引,用于地理数据存储,无前缀查询;使用如MBRCONTAINS()来维护数据
    5.全文索引:查找文本中的关键词,而不是直接比较索引中的值,不是简单的where条件匹配
    6.索引命中策略:
       a.独立的列:索引列不能是表达式的一部分,也不能是函数的参数
        如:select a from test wher a+1=5;--->无法命中a列,因为MySQL无法解析
       b.前缀索引和索引选择性(不重复索引值和数据表的记录总数(#T)的比值,范围1/#T到1之间)
         MySQL无法使用前缀索引做ORDER BY和GROUP BY,也无法使用前缀索引做覆盖扫描
    7.多列索引: explain的key列可看到索引命中列-->Using index
        a.当出现服务器对多个索引做相交操作时(通常由多个and条件),意味着需要一个包含所有相关列的多列索引,而非多个独立的单列索引
        b.当需要对多个索引做联合操作(有多个OR条件);另外优化器不会将这些计算归到"查询成本",只关心随机页面读取,最终导致执行计划还不如走全表扫描
        c.可通过optimizer_switch来关闭索引合并功能,也可使用ignore index提示优化器忽略掉某些索引
   8.选择合适的索引列顺序:
       a.B-Tree:索引按照最左列进行排序;通常建议:当不需要考虑排序和分组时,将选择性最高的列放到索引最前列
   9.聚簇索引:不是一种单独的索引类型,而是一种数据存储方式,一个表只能由一个聚簇索引(覆盖索引可模拟多个聚簇索引);InnoDB通过主键聚集数据,如果没有定义主键,会选择一个唯一的非空索引代替,如果没有这样的索引,会隐式定义一个主键来作为聚簇索引
     二级索引叶子节点保存的不是指向行的物理位置的指针,而是行的主键值
    MyISAM的数据分布:按照数据插入的顺序存储在磁盘上
    InnoDB中聚簇索引:每一个节点都包含了主键值、事务ID、用于事务和MVCC的回滚指针以及所有的剩余列;定义代理主键,可用AUTO_INCREMEN作为自增列(主键顺序可能会造成明显的争用,上界会成为"热点",还有AUTO_INCREMENT的锁机制,如果遇到可能需要重新设计表或应用或innodb_autonic_lock_mode);避免随机的(不连续且值的分布范围非常大)聚簇索引。
    UUID主键插入行不仅花费的时间更长,且索引占用的空间也更大,是因为主键字段更长和页分裂和碎片导致的
    10.覆盖索引:一个索引包含(覆盖)所有需要查询的字段的值(必须要存储索引列的值)
    好处:a.索引条目通常远小于数据行大小 b.索引是按列值顺序存储的,对I/O密集型的范围查询会比随机从磁盘读取每一行数据的I/O要少得多
    c.InnoDB的聚簇索引特性,二级索引在叶子节点中保存了行的主键值,因此当二级主键能覆盖查询,则可避免对主键索引的二次查询。
      MySQL不能在索引中执行LIKE操作->可采用延迟关联做一下处理
    11.使用索引扫描来做排序:
        a.通过排序操作  b.按索引顺序扫描   explain出来的type列的值为“index”,则说明MySQL使用了索引扫描来做排序
        只有当索引的列顺序和ORDER BY子句的顺序完全一致,且所有列的排序放心都一样时,才能使用索引来对结果进行排序;
        如果查询需要关联多张表,则只有当ORDER BY子句引用的字段全部为第一个表时,才能使用索引做排序
        最左前缀(前导列为常量的时候,可不满足此要求)
    12.压缩(前缀压缩)索引:MyISAM使用前缀压缩来减少索引的大小,从而让更多的索引放入内存中,默认只压缩字符串
    13.重复索引:在相同的列上按照相同的顺序创建的相同类型的索引,应避免,发现后应立即删除
        MySQL的唯一限制和主键限制本质上是通过索引实现
        冗余索引:创建了索引(A,B),再创建索引(A)则(A)就是冗余索引
        一般增加新索引会导致INSERT、UPDATE、DELETE等操作的速度变慢,特别是当新增索引后导致达到了内存瓶颈的时候
六、查询性能优化:
    1.查询的声明周期:从客户端到服务器,然后在服务器上解析,生成执行计划,执行,并返回结果给客户端。执行可认为是整个声明周期中最重要的阶段,包含了为检索数据都存储引擎的调用以及调用后的数据处理,包括排序、分组等
    2.查询性能低下最基本原因是访问的数据太多,分析:
       a.确认应用程序是否在检索大量超过需要的数据
       b.确认MySQL服务器层是否在分析大量超过需要的数据行
    3.常见 慢查询案例:
       a.查询不需要的记录,如开发者先用SELECT语句查询大量的结果,再获取前N行后关闭结果集。解决办法:查询后加LIMIT
       b.多表关联时返回全部列,select a from a inner join b using(id) inner join c using(name) where age=1--> select a.* from 
       c.总是取出全部列
       d.重复查询相同的数据  修改:缓存初次查询的数据
    4.衡量查询开销的指标:
       a.响应时间(服务时间、排队时间之和)    b.扫描的行数    c.返回的行数
       EXPLAIN中的type反应了访问类型: 一般MySQL中以下三种方式使用WHERE条件:
       a.在索引中使用WHERE条件来过滤不匹配的记录
       b.使用索引覆盖扫描(在Extra列中出现了Using Index),直接从索引中过滤不需要的记录并返回命中的结果
       c.从数据表中返回结果,然后过滤不满足条件的记录(Extra中出现了Using where)
       当发现查询需要扫描大量的数据但只返回少数的行,尝试如下方式优化:
            a.使用索引覆盖扫描,把所有需要用到的列都放到索引中,这样存储引擎无须回表获取对应行就可返回结果了
            b.改变库表结构,例如使用单独的汇总表
            c.重写这个复杂的查询
    5.重构查询的方式:
       a.一个复杂查询可考虑拆分成多个简单查询,前提是能减少工作量
       b.拆分查询:将大查询切分成多个小查询,每个查询功能完全一样,只完成一小部分,每次返回一小部分查询结果  如定期删除旧数据,如果一个大删除语句一次性完成,则可能需要一次锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞其他查询等操作
       c.分解关联查询:可对每一个表进行一次单表查询,然后将结果在应用程序中进行关联
        优点:1.让缓存的效率更高,因为应用一般会缓存大表查询对应的结果对象
                   2.将查询分解后,执行单个查询可减少锁的竞争
                   3.应用层做关联,可更容易对数据库进行拆分,更容易做到高性能和可扩展
                   4.查询本身效率也可能会提升,使用in(部分id)代替关联查询,会比随机的关联更搞效
                   5.可减少冗余数据的查询
        d.查询执行的过程:
          1.客户端发送一条查询给服务器
          2.服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果。否则进入下一阶段
          3.服务器端进行SQL解析、预处理,再由优化器生成对应的执行计划
          4.MySQL根据优化器生成的执行计划,调用存储引擎的API执行查询,最后返回结果
               
        e.MySQL客户端/服务器端通信协议:"半双工",在任何一个时刻,要么是由服务器想客户端发送数据,要么是客户端向服务器发送数据,这两个动作不能同时发生。
          多数连接MySQL的库函数都可获得全部结果集并缓存到内存里,还可逐行获取需要的数据。默认一般是获得全部结果集并缓存到内存中
        f.  查询状态:show full processlist 返回的结果中Command列可表示当前的状态
            Sleep:线程正在等待客户端发送新请求
            Query:线程正在执行查询或正在将结果发送给客户端
            Locked:在MySQL服务器层中,该线程正在等待表锁。在存储引擎级别实现的锁,如InnoDB的行锁,不会体现在线程状态中。
            Analying and statistics:线程正在收集存储引擎的统计信息,并生成查询的执行计划
            Copying to tmp table[on disk]:线程正在执行查询,并将结果集都复制到一个临时表中,这种状态一般是GROUP BY操作,要么是文件排序操作或UNION操作
            Sorting result:线程正在对结果进行排序
            Sending data:线程可能在多个状态之间传送数据,或者生成结果集或者想客户端返回数据
        
      6.查询优化处理:
        a.语法解析器和预处理:MySQL通过关键字将SQL语句进行解析,并生成一棵对应的"解析树"。MySQL解析器将使用MySQL语法规则验证和解析查询;通过SHOW STATUS LIKE 'Last_query_cost' 可看当前查询的成本Last_query_cost=2代表需要2个数据页的随机查找才能完成上述查询(页)
        b.优化策略:
            1.静态优化(编译时优化):直接对解析树进行分析并完成优化
            2.动态优化(运行时优化):和查询的上下文有关
               MySQL对查询的静态优化只需要做一次,但对动态优化则在每次执行时都需要重新评估
       7.MySQL关联执行的策略:对任何关联都执行嵌套循环关联操作,即现在一个表中循环取出单条数据,然后再嵌套循环到下一个表中寻找匹配的行,依次循环直到找到所有表中匹配的行。
       8.执行计划:MySQL生成查询的一棵指令树,然后通过存储引擎执行完成这棵指令树并返回结果。EXPLAIN EXTEND和执行SHOW WARNINGS,就可重构出查询
        





































       





































































































































































































猜你喜欢

转载自www.cnblogs.com/linzx2015/p/10887934.html