MySQL查询优化,MySQL优化

by admin on 2019年9月12日

MySQL 查询优化之 Block Nested-Loop 与 Batched Key Access Joins

在MySQL中,可以使用批量密钥访问(BKA)连接算法,该算法使用对连接表的索引访问和连接缓冲区。

BKA算法支持:内连接,外连接和半连接操作,包括嵌套外连接。

BKA的优点:更加高效的表扫描提高了连接性能。

此外,先前仅用于内连接的块嵌套循环(BNL)连接算法现已扩展,可用于外连接半连接操作,包括嵌套外连接

以下部分讨论了连接缓冲区管理,它是原始BNL算法扩展,扩展BNL算法和BKA算法的基础。
有关半连接策略的信息,请参见“使用半连接转换优化子查询,派生表和视图引用”

  • Nested Loop Join
    算法

  • Block Nested-Loop
    算法

  • Batched Key Access
    算法

  • BNL和BKA算法的优化器Hint

SELECT Room.RoomID, Class.Time
FROM Room
   FULL OUTER JOIN Class
   ON Room.RoomID = Class.RoomID
ORDER BY Room.RoomID;

MySQL查询优化,MySQL优化

一、原理

此文章主要向大家描述的是MySQL查询优化系列之MySQL查询优化器,当你在对一查询进行提交的时候,MySQL数据库会对它进行分析,主要是看其是否可以用来做一些优化使处理该查询的速度更快。

奥门威尼斯网址 ,Nested Loop Join算法

将外层表的结果集作为循环的基础数据,然后循环从该结果集每次一条获取数据作为下一个表的过滤条件去查询数据,然后合并结果。如果有多个表join,那么应该将前面的表的结果集作为循环数据,取结果集中的每一行再到下一个表中继续进行循环匹配,获取结果集并返回给客户端。

伪代码如下

for each row in t1 matching range {
  for each row in t2 matching reference key {
     for each row in t3 {
      if row satisfies join conditions,
      send to client
    }
  }
 }

 

普通的Nested-Loop
Join算法一次只能将一行数据传入内存循环,所以外层循环结果集有多少行,那么内存循环就要执行多少次。

1、简介

   
 一个好的web应用,最重要的一点是有着优秀的访问性能。数据库MySQL是web应用的组成部分,也是决定其性能的重要部分。所以提升MySQL的性能至关重要。

   
 MySQL性能的提升可分为三部分,包括硬件、网络、软件。其中硬件、网络取决于公司的财力,需要白哗哗的银两,这里就不说啦。软件又细分为很多种,在这里我们通过MySQL的查询优化从而达到性能的提升。

     最近看了一些关于查询优化的书籍,同时也在网上看一些前辈们写的文章。

以下是自己整理借鉴关于查询优化的一些总结:

1.1 Nest-Loop Join

这一部分将介绍查询优化器是如何工作的。如果你想知道MySQL(和PHP搭配之最佳组合)采用的优化手段,可以查看MySQL(和PHP搭配之最佳组合)参考手册。

Block Nested-Loop算法

MySQL
BNL算法原本只支持内连接,现在已支持外连接半连接操作,包括嵌套外连接

BNL算法原理:将外层循环的行/结果集存入join
buffer,内存循环的每一行数据与整个buffer中的记录做比较,可以减少内层循环的扫描次数

举个简单的例子:外层循环结果集有1000行数据,使用NLJ算法需要扫描内层表1000次,但如果使用BNL算法,则先取出外层表结果集的100行存放到join
buffer,
然后用内层表的每一行数据去和这100行结果集做比较,可以一次性与100行数据进行比较,这样内层表其实只需要循环1000/100=10次,减少了9/10。

伪代码如下

for each row in t1 matching range {
   for each row in t2 matching reference key {
    store used columns from t1, t2 in join buffer
    if buffer is full {
      for each row in t3 {
         for each t1, t2 combination in join buffer {
          if row satisfies join conditions,
          send to client
        }
        }
       empty buffer
     }
   }
 }

 if buffer is not empty {
    for each row in t3 {
     for each t1, t2 combination in join buffer {
       if row satisfies join conditions,
       send to client
      }
   }
 }

 

如果t1, t2参与join的列长度只和为s, c为二者组合数, 那么t3表被扫描的次数为

(S * C)/join_buffer_size + 1

 

扫描t3的次数随着join_buffer_size的增大而减少, 直到join
buffer能够容纳所有的t1, t2组合, 再增大join buffer size, query
的速度就不会再变快了。

 

optimizer_switch系统变量的block_nested_loop标志控制优化器是否使用块嵌套循环算法。

默认情况下,block_nested_loop已启用。

在EXPLAIN输出中,当Extra值包含Using join buffer(Block Nested Loop)type值为ALL,index或range时,表示使用BNL。

示例

mysql> explain SELECT  a.gender, b.dept_no FROM employees a, dept_emp b WHERE a.birth_date = b.from_date;
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra                                              |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+
|  1 | SIMPLE      | a     | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 298936 |   100.00 | NULL                                               |
|  1 | SIMPLE      | b     | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 331143 |    10.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)

 

2、截取SQL语句

     1、全面查询日志

     2、慢查询日志

     3、二进制日志

     4、进程列表

  SHOW FULL PROCESSLIST;

  。。。

NLJ算法:将驱动表/外部表的结果集作为循环基础数据,然后循环从该结果集每次一条获取数据作为下一个表的过滤条件查询数据,然后合并结果。如果有多表join,则将前面的表的结果集作为循环数据,取到每行再到联接的下一个表中循环匹配,获取结果集返回给客户端。

当然,MySQL(和PHP搭配之最佳组合)查询优化器也利用了索引,但是它也使用了其它一些信息。例如,如果你提交如下所示的查询,那么无论数据表有多大,MySQL(和PHP搭配之最佳组合)执行它的速度都会非常快:

Batched Key Access 算法

对于多表join语句,当MySQL使用索引访问第二个join表的时候,使用一个join
buffer来收集第一个操作对象生成的相关列值。BKA构建好key后,批量传给引擎层做索引查找。key是通过MRR接口提交给引擎的,这样,MRR使得查询更有效率。

如果外部表扫描的是主键,那么表中的记录访问都是比较有序的,但是如果联接的列是非主键索引,那么对于表中记录的访问可能就是非常离散的。因此对于非主键索引的联接,Batched
Key Access
Join算法将能极大提高SQL的执行效率。BKA算法支持内连接,外连接和半连接操作,包括嵌套外连接。

Batched Key Access Join算法的工作步骤如下:

  • 1) 将外部表中相关的列放入Join Buffer中。

  • 2) 批量的将Key(索引键值)发送到Multi-Range Read(MRR)接口。

  • 3) Multi-Range
    Read(MRR)通过收到的Key,根据其对应的ROWID进行排序,然后再进行数据的读取操作。

  • 4) 返回结果集给客户端。

Batched Key Access Join算法的本质上来说还是Simple Nested-Loops
Join算法,其发生的条件为内部表上有索引,并且该索引为非主键,并且联接需要访问内部表主键上的索引。这时Batched
Key Access Join算法会调用Multi-Range
Read(MRR)接口,批量的进行索引键的匹配和主键索引上获取数据的操作,以此来提高联接的执行效率,因为读取数据是以顺序磁盘IO而不是随机磁盘IO进行的。

使用BKA时,join_buffer_size的值定义了对存储引擎的每个请求中批量密钥的大小。缓冲区越大,对连接操作的右侧表的顺序访问就越多,这可以显着提高性能。

要使用BKA,必须将optimizer_switch系统变量的batched_key_access标志设置为on。
BKA使用MRR,因此mrr标志也必须打开。目前,MRR的成本估算过于悲观。因此,mrr_cost_based也必须关闭才能使用BKA。

以下设置启用BKA:

mysql> SET optimizer_switch='mrr=on,mrr_cost_based=off,batched_key_access=on';

 

在EXPLAIN输出中,当Extra值包含Using join buffer(Batched Key Access)且类型值为refeq_ref时,表示使用BKA。

示例:

mysql> show index from employees;
+-----------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table     | Non_unique | Key_name       | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| employees |          0 | PRIMARY        |            1 | emp_no      | A         |      298936 |     NULL | NULL   |      | BTREE      |         |               |
| employees |          1 | idx_name       |            1 | last_name   | A         |        1679 |     NULL | NULL   |      | BTREE      |         |               |
| employees |          1 | idx_name       |            2 | first_name  | A         |      277495 |     NULL | NULL   |      | BTREE      |         |               |
| employees |          1 | idx_birth_date |            1 | birth_date  | A         |        4758 |     NULL | NULL   |      | BTREE      |         |               |
+-----------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec)


mysql> explain SELECT a.gender, b.dept_no FROM employees a, dept_emp b WHERE a.birth_date = b.from_date;
+----+-------------+-------+------------+------+----------------+----------------+---------+-----------------------+--------+----------+-------+
| id | select_type | table | partitions | type | possible_keys  | key            | key_len | ref                   | rows   | filtered | Extra |
+----+-------------+-------+------------+------+----------------+----------------+---------+-----------------------+--------+----------+-------+
|  1 | SIMPLE      | b     | NULL       | ALL  | NULL           | NULL           | NULL    | NULL                  | 331143 |   100.00 | NULL  |
|  1 | SIMPLE      | a     | NULL       | ref  | idx_birth_date | idx_birth_date | 3       | employees.b.from_date |     62 |   100.00 | NULL  |
+----+-------------+-------+------------+------+----------------+----------------+---------+-----------------------+--------+----------+-------+

#使用hint,强制走bka

mysql> explain SELECT /*+ bka(a)*/ a.gender, b.dept_no FROM employees a, dept_emp b WHERE a.birth_date = b.from_date;
+----+-------------+-------+------------+------+----------------+----------------+---------+-----------------------+--------+----------+----------------------------------------+
| id | select_type | table | partitions | type | possible_keys  | key            | key_len | ref                   | rows   | filtered | Extra                                  |
+----+-------------+-------+------------+------+----------------+----------------+---------+-----------------------+--------+----------+----------------------------------------+
|  1 | SIMPLE      | b     | NULL       | ALL  | NULL           | NULL           | NULL    | NULL                  | 331143 |   100.00 | NULL                                   |
|  1 | SIMPLE      | a     | NULL       | ref  | idx_birth_date | idx_birth_date | 3       | employees.b.from_date |     62 |   100.00 | Using join buffer (Batched Key Access) |
+----+-------------+-------+------------+------+----------------+----------------+---------+-----------------------+--------+----------+----------------------------------------+
2 rows in set, 1 warning (0.00 sec)

 

3、查询优化基本分析命令

  1、EXPLAIN {PARTITIONS|EXTENDED}

  2、SHOW CREATE TABLE tab;

  3、SHOW INDEXS FROM tab;

  4、SHOW TABLE STATUS LIKE ‘tab’;

  5、SHOW [GLOBAL|SESSION] STATUS LIKE ‘’;

  6、SHOW VARIABLES

  。。。。

  ps:我自己都感觉上面都是没任何营养的东西。下面才是真正的干货哈。

NJL伪代码:

SELECT * FROM tbl_name WHERE 0; 

BNL和BKA算法的优化器Hint

除了使用optimizer_switch系统变量来控制优化程序在会话范围内使用BNL和BKA算法之外,MySQL还支持优化程序提示,以便在每个语句的基础上影响优化程序。
请参见“优化程序Hint”。

要使用BNL或BKA提示为外部联接的任何内部表启用联接缓冲,必须为外部联接的所有内部表启用联接缓冲。

奥门威尼斯网址 1

使用qb_name

SELECT /*+ QB_NAME(qb1) MRR(@qb1 t1) BKA(@qb2) NO_MRR(@qb3t1 idx1, id2) */ ...
  FROM (SELECT /*+ QB_NAME(qb2) */ ...
  FROM (SELECT /*+ QB_NAME(qb3) */ ... FROM ...)) ...

 

4、查询优化几个方向

  1、尽量避免全文扫描,给相应字段增加索引,应用索引来查询

  2、删除不用或者重复的索引

  3、查询重写,等价转换(谓词、子查询、连接查询)

  4、删除内容重复不必要的语句,精简语句

  5、整合重复执行的语句

  6、缓存查询结果

    for each row in t1 matching range {
      for each row in t2 matching reference key {
         for each row in t3 {
          if row satisfies join conditions,
          send to client
        }
      }
     }

在这个例子中,MySQL(和PHP搭配之最佳组合)查看WHERE子句,认识到没有符合查询条件的数据行,因此根本就不考虑搜索数据表。你可以通过提供一个EXPLAIN语句看到这种情况,这个语句让MySQL(和PHP搭配之最佳组合)显示自己执行的但实际上没有真正地执行的SELECT查询的一些信息。如果要使用EXPLAIN,只需要在EXPLAIN单词放在SELECT语句的前面:

5、索引优化

可以看到,NLJ每次只会将一行传入内层循环,外层循环的结果集有多少行,内层循环就要执行多少次,如果内层表较大,或没关联字段没索引的情况下,执行效率就会很差

MySQL(和PHP搭配之最佳组合)> EXPLAIN SELECT * FROM tbl_name WHERE 0\G  id: 1  select_type: SIMPLE  table: NULL  type: NULL  possible_keys: NULL  key: NULL  key_len: NULL  ref: NULL  rows: NULL  Extra: Impossible WHERE   

  5.1、索引优点:

    1、保持数据的完整性

    2、提高数据的查询性能

    3、改进表的连接操作(jion)

    4、对查询结果进行排序。没索引将会采用内部文件排序算法进行排序,效率较慢

    5、简化聚合数据操作

1.2 Block Nest-Loop Join

通常情况下,EXPLAIN返回的信息比上面的信息要多一些,还包括用于扫描数据表的索引、使用的联结类型、每张数据表中估计需要检查的数据行数量等非空NULL)信息。

  5.2、索引缺点

    1、索引需要占用一定的存储空间

    2、数据插入、更新、删除时会受索引的影响,性能会降低。因为数据变更索引也需要进行更新

    3、多个索引,优化器需要耗时则优选择

BNL算法:将外层循环的行/结果存入join
buffer,内层循环的每一行与整个buffer中的记录做比较,从而减少循环的次数。

优化器是如何工作的

  5.3、索引选择

    1、数据量大时采用

    2、数据高度重复时,不采用

    3、查询取出数据大于20%,将采用全文扫描,不用索引

举例来说,外层循环的结果集是100行,使用NLJ
算法需要扫描内部表100次,如果使用BNL算法,先把对Outer
Loop表(外部表)每次读取的10行记录放到join
buffer,然后在InnerLoop表(内部表)中直接匹配这10行数据,内存循环就可以一次与这10行进行比较,
这样只需要比较10次,对内部表的扫描减少了9/10。所以BNL算法就能够显著减少内层循环表扫描的次数。

MySQL(和PHP搭配之最佳组合)查询优化器有几个目标,但是其中最主要的目标是尽可能地使用索引,并且使用最严格的索引来消除尽可能多的数据行。你的最终目标是提交SELECT语句查找数据行,而不是排除数据行。

  5.4、索引细究

    资料查询:

    MySQL中的InnoDB、MyISAM都是B-Tree类型索引

    B-Tree包含:PRIMARY KEY, UNIQUE, INDEX, and FULLTEXT

    B-Tree类型索引不支持(即字段使用以下符号时,将不采用索引):

    >, <, >=, <=, BETWEEN, !=, <>,like ‘%**’

    【在此先介绍一下覆盖索引】

    以我自己理解的方式介绍吧。覆盖索引并不是像主键索引、唯一索引一样真实存在,它只是对索引应用某些特定场景的一种定义【另一种理解:查询的列是索引列,因此列被索引覆盖】。它可以突破传统的限制,使用以上操作符,且依然采用索引进行查询。

    因为查询的列是索引列,所以不需要读取行,只需要读取列字段数据就可以了。【例如你看一本书,需要找某一内容,刚好那内容出现在目录中,那就不用一页页翻了,直接在目录中定位到第几页查找】

    如何激活覆盖索引呢?什么样才是特定场景呢?

    索引字段,在select中出现就是了。

    复合索引还可能有其他的特殊场景。例如,三列复合索引,仅需要在select、where、group
by、order
by中,任意一个地方出现一次复合索引最左边列就可以激活使用覆盖索引了。

    查看:

    EXPLAIN中Extra显示有Using index表示这条语句采用了覆盖索引。

    结论:

    不建议在查询的时候使用select*from进行查询了,应该写需要用的字段,并且增加相应的索引,以提高查询性能。

    针对以上操作符实测结果:

    1、以select*from形式,where中是primary
key可以通杀【除like】(使用主键进行查询);index则全不可以。

    2、以select 字段a from tab where
字段a《以上操作符》形式测试,结果依然可以使用索引查询。【采用了覆盖索引】

    其他索引优化方法:

    1、使用索引关键字作为连接的条件

    2、复合索引使用

    3、索引合并or and,将涉及到的字段合并成复合索引

    4、where、和group by涉及字段加索引

BNL伪代码:

优化器试图排除数据行的原因在于它排除数据行的速度越快,那么找到与条件匹配的数据行也就越快。如果能够首先进行最严格的测试,查询就可以执行地更快。假设你的查询检验了两个数据列,每个列上都有索引:

6、子查询优化

  在from中为非相关子查询,可以上拉子查询到父层。在多表连接查询考虑连接代价再选择。

  查询优化器对子查询一般采用嵌套执行的方式,即对父查询中的每一行,都执行一次子查询,这样子查询会执行很多次。这种执行方式效率很低。

  子查询转化为连接查询优点:

  1、子查询不用执行很多次

  2、优化器可以根据信息来选择不同的方法和连接顺序

  3、子查询的连接条件,过滤条件变成父查询的筛选条件,以提高效率。

  优化:

  子查询合并,若多个子查询,能合并的尽量合并。

  子查询展开,即上拉变成多表查询(时刻保证等价变化)

  注意:

  子查询展开只能展开简单的查询,若子查询含有聚集函数、GROUP
BY、DISTINCT,则不能上拉。

  select * from t1 (select*from tab where id>10) as t2 where
t1.age>10 and t2.age<25;

  select*from t1,tab as t2 where t1.age>10 and t2.age<25 and
t2.id>10;

  具体步骤:

  1、from与from合并,修改相应参数

  2、where与where合并,用and连接

  3、修改相应的谓词(in改=)

    for each row in t1 matching range {
       for each row in t2 matching reference key {
        store used columns from t1, t2 in join buffer
        if buffer is full {
          for each row in t3 {
             for each t1, t2 combination in join buffer {
              if row satisfies join conditions,
              send to client
            }
           }
          empty buffer
        }
      }
    }


    if buffer is not empty {
       for each row in t3 {
        for each t1, t2 combination in join buffer {
          if row satisfies join conditions,
          send to client
         }
      }
    }
SELECT col3 FROM mytable  WHERE col1 = ’some value’ AND col2 = ’some other value’; 

7、等价谓词重写:

  1、BETWEEEN AND改写为 >=
、<=之类的。实测:十万条数据,重写前后时间,1.45s、0.06s

  2、in转换多个or。字段为索引时,两个都能用到索引,or效率相对in好一点

  3、name like ‘abc%’改写成name>=’abc’ and name<’abd’;

  注意:百万级数据测试,name没有索引之前like比后一种查询快;给字段增加索引后,后面的快一点点,相差不大,因为两种方法在查询的时候都用到了索引。

  。。。。

二、JOIN BUFFER

假设col1上的测试匹配了900个数据行,col2上的测试匹配了300个数据行,而同时进行的测试只得到了30个数据行。先测试Col1会有900个数据行,需要检查它们找到其中的30个与col2中的值匹配记录,其中就有870次是失败了。

8、条件化简与优化

  1、将where、having(不存在groupby和聚集函数时)、join-on条件能合并的尽量合并

  2、删除不必要的括号,减少语法分许的or和and树层,减少cpu消耗

  3、常量传递。a=b and b=2转换为 a=2 and
b=2。尽量不使用变量a=b或[email protected]

  4、消除没用的SQL条件

  5、where等号右边尽量不出现表达式计算;where中不要对字段进行表达式计算、函数的使用

  6、恒等变换、不等式变换。例:测试百万级数据a>b and
b>10变为a>b and a>10 and b>10优化显著

2.1 mysql中join buffer的注意事项

先测试col2会有300个数据行,需要检查它们找到其中的30个与col1中的值匹配的记录,只有270次是失败的,因此需要的计算和磁盘I/O更少。其结果是,优化器会先测试col2,因为这样做开销更小。

9、外连接优化

  即将外连接转为内连接

  优点:

  1、优化处理器处理外连接比内连接步骤多且耗时

  2、外连接消除后,优化器选择多表连接顺序有更多选择,可以择优而选

  3、可以将筛选条件最为严格的表作为外表(连接顺序最前面,是多层循环体的外循环层),

  可以减少不必要的I/O开销,能加快算法执行的速度。

  on a.id=b.id与where
a.id=b.id的差别,on则表进行连接,where则进行数据对比

  注意:前提必须是结果为NULL决绝(即条件限制不要NULL数据行,语意上是内连接)

  优化原则:

  精简查询,连接消除,等效转换,去除多余表对象连接

  例如:主键/唯一键作为连接条件,且中间表列只作为等值条件,可以去掉中间表连接

1、join_buffer_size变量决定buffer大小。
2、只有在join类型为all、index、range的时候才可以使用join buffer
3、能够被buffer的每一个join都会分配一个buffer,一个quary最终可能会有多个buffer
4、第一个nonconst table不会分配join
buffer,即使其扫描类型是all或者index
5、join buffer中只会保存参与join的列,并非整个数据行

以上的相关内容就是对MySQL查询优化系列讲座之查询优化器的介绍,望你能有所收获。

10、其他查询优化

  1、以下将会造成放弃索引查询,采用全文扫描

    1.1、where
子句中使用!=或<>操作符  注意:主键支持。非主键不支持

    1.2、避免使用or

      经测试,并非是使用了or就一定不能使用索引,大多情况下是没用到索引,但还有少数情况是用到的,因此具体情况具体分析。

      类似优化:

      select * from tab name=’aa’ or name=’bb’;

      =>

      select * from tab name=’aa’

      union all

      select * from tab name=’bb’;

      实测:

      1、十万数据测试,没任何索引的情况下,上面比下面的查询速率快一倍。

      2、三十万数据测试,aa与bb都是单独索引情况下,下面的查询速率比or快一点。

    1.3、避免使用not in

      not in一般不能使用索引;主键字段可以

    1.4、where中尽量避免使用对null的判断

    1.5、like不能前置百分号 like ‘%.com’

      解决:

        1、若必须使用%前置,且数据长度不大,例如URL,可将数据翻转存入数据库,再来查。LIKE
REVERSE‘%.com’;

        2、使用覆盖索引

 

    1.6、使用索引字段作为条件的时候,假若是复合索引,则应该使用索引最左边前缀的字段名

  2、将exists代替in

    select num from a where num in(select num from b)

    select num from a where exists(select 1 from b where num=a.num)

    一百万条数据,筛选59417条数据用时6.65s、4.18s。没做其他优化,仅仅只是将exists替换in。

  3、字段定义是字符串,查询时没带引号,不会用索引,将会进行全文扫描。

  【以下是摘抄于半夜乱弹琴博文

  4、尽量使用表变量来代替临时表

  5、避免频繁创建和删除临时表,以减少系统表资源的消耗

  6、如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先
truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定

  7、尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写

  8、大数据量,若数据量过大,应该考虑相应需求是否合理。

  9、尽量避免大事务操作,提高系统并发能力。

  。。。。。

三、如何使用BNL

11、博文总结

  经过这些天查资料敲代码的学习,了解到了MySQL的查询优化并不是简简单单的按照某个公式某个规则就可达到的。实验是检验标准的唯一标准,经过这几天的测试,得出的结论就是:MySQL的查询优化是有大方向,但是想要得出一个万能优化公式那是不可能的,毕竟每一条SQL查询语句的写法、结果着重点、以及表的字段环境都不一样。能够达到看SQL查询语句就能得出优化方法的大神,必定是仔细研究过SQL查询优化并且有过好几年优化经验的老鸟。哈哈,我还只是个小菜鸟。

  建议各位正在学习SQL查询优化的童鞋们:不要仅仅只是看,要多敲代码,多测试,各种字段环境测试、各种数据量级别测试。

 

以上是自己的一些总结,也许有些不足。毕竟自己还只是个菜鸟,并且也不是DBA的方向,若大家发现有不足的地方,或者错误的地方,请您能够提出来。

 

作者:壹叶随风

声明:转载时请在文章页面明显位置给出原文链接。

1、简介
一个好的web应用,最重要的一点是有着优秀的访问性能。数据库MySQL是web应用的组成部分,也是决定其性能…

5.6版本及以后,优化器管理参数optimizer_switch中中的block_nested_loop参数控制着BNL是否被用于优化器。默认条件下是开启,若果设置为off,优化器在选择
join方式的时候会选择NLJ算法。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图