派生表和视图的性能

从MySQL 4.1开始,它已经支持派生表、联机视图或者基本的FROM从句的子查询。

这些特性之间彼此相关,但是它们之间的性能比较如何呢?

MySQL 5.0 中的派生表似乎和视图实现的方式不同,尽管我从合并的代码基数来看觉得在查询优化上应该是一样的。

派生表仍然以临时表的方式显式地处理,而且还是没有索引的临时表(因此最好不要像在例子中那样连接2个派生表)

需要考虑的另一方面是,派生表需要被显式处理,尽管只是执行 EXPLAIN 语句。因此如果在 FROM 字句中的 SELELCT 操作上犯了错误,例如忘记了写上连接的条件,那么 EXPLAIN 可能会一直在运行。

视图则不同,它无需被显式处理,只是把查询简单地重写了一下。只有在无法合并查询或者试图创建者请求时才需要被显式处理。

这意味着它们在性能上的差别如下:

在基本的表上执行有索引 的查询,这非常快

  1. mysql> SELECT * FROM test WHERE i=5 ;
  2. +---+----------------------------------+
  3. | i | j                                |
  4. +---+----------------------------------+
  5. | 5 | 0c88dedb358cd96c9069b73a57682a45 |
  6. +---+----------------------------------+
  7. 1 row IN SET ( 0 .03 sec)
mysql> SELECT * FROM test WHERE i=5 ;
+---+----------------------------------+
| i | j |
+---+----------------------------------+
| 5 | 0c88dedb358cd96c9069b73a57682a45 |
+---+----------------------------------+
1 row IN SET ( 0 .03 sec)

在派生表上做同样的查询,则如老牛拉破车

  1. mysql> SELECT * FROM ( SELECT * FROM test) t WHERE i=5 ;
  2. +---+----------------------------------+
  3. | i | j                                |
  4. +---+----------------------------------+
  5. | 5 | 0c88dedb358cd96c9069b73a57682a45 |
  6. +---+----------------------------------+
  7. 1 row IN SET ( 1 min 40 .86 sec)
mysql> SELECT * FROM ( SELECT * FROM test) t WHERE i=5 ;
+---+----------------------------------+
| i | j |
+---+----------------------------------+
| 5 | 0c88dedb358cd96c9069b73a57682a45 |
+---+----------------------------------+
1 row IN SET ( 1 min 40 .86 sec)

在视图上查询,又快起来了 

  1. mysql> CREATE VIEW v AS SELECT * FROM test;
  2. Query OK, 0 rows affected ( 0 .08 sec)
  3. mysql> SELECT * FROM v  WHERE i=5 ;
  4. +---+----------------------------------+
  5. | i | j                                |
  6. +---+----------------------------------+
  7. | 5 | 0c88dedb358cd96c9069b73a57682a45 |
  8. +---+----------------------------------+
  9. 1 row IN SET ( 0 .10 sec)
mysql> CREATE VIEW v AS SELECT * FROM test;
Query OK, 0 rows affected ( 0 .08 sec) mysql> SELECT * FROM v WHERE i=5 ;

+---+----------------------------------+

| i | j |

+---+----------------------------------+

| 5 | 0c88dedb358cd96c9069b73a57682a45 |

+---+----------------------------------+

1 row IN SET ( 0 .10 sec)

下面的2条EXPLAIN结果也许会让你很惊讶

  1. mysql> EXPLAIN SELECT * FROM v  WHERE i=5 ;
  2. +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
  3. | id | select_type | TABLE | type  | possible_keys | KEY      | key_len | ref   | rows | Extra |
  4. +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
  5. |  1 | PRIMARY      | test  | const | PRIMARY        | PRIMARY | 4        | const |    1 |       |
  6. +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
  7. 1 row IN SET ( 0 .02 sec)
  8. mysql> EXPLAIN SELECT * FROM ( SELECT * FROM test) t WHERE i=5 ;
  9. +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+
  10. | id | select_type | TABLE       | type | possible_keys | KEY   | key_len | ref  | rows    | Extra       |
  11. +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+
  12. |  1 | PRIMARY      | <derived2> | ALL   | NULL           | NULL | NULL     | NULL | 1638400 | USING WHERE |
  13. |  2 | DERIVED     | test       | ALL   | NULL           | NULL | NULL     | NULL | 1638400 |             |
  14. +----+-------------+------------+------+---------------+------+---------+------+---------+-------------+
  15. 2 rows IN SET ( 54 .90 sec)
mysql> EXPLAIN SELECT * FROM v  WHERE i=5 ;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | TABLE | type | possible_keys | KEY | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| 1 | PRIMARY | test | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
1 row IN SET ( 0 .02 sec) mysql> EXPLAIN SELECT * FROM ( SELECT * FROM test) t WHERE i=5 ;

+----+-------------+------------+------+---------------+------+---------+------+---------+-------------+

| id | select_type | TABLE | type | possible_keys | KEY | key_len | ref | rows | Extra |

+----+-------------+------------+------+---------------+------+---------+------+---------+-------------+

| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 1638400 | USING WHERE |

| 2 | DERIVED | test | ALL | NULL | NULL | NULL | NULL | 1638400 | |

+----+-------------+------------+------+---------------+------+---------+------+---------+-------------+

2 rows IN SET ( 54 .90 sec)

避免使用派生表 -- 如果可能,最好采用其他方式来编写查询语句,大部分情况都比派生表来的快。很多情况下,甚至连独立的临时表都来的快,因为可以适当增加索引。

可以考虑使用临时试图来取代派生表 如果确实需要在 FROM 子句中使用到子查询,可以考虑在查询时创建试图,当查询完之后删除试图。

不适合多表视图,多表时用派生表取代视图

  1. explain  select sum(pdm.qty) pre_total,pd.pre_doc_id from prepare_doc pd
  2. left join pre_doc_item pdm on pd.pre_doc_id=pdm.pre_doc_id group by pd.pre_doc_id
explain  select sum(pdm.qty) pre_total,pd.pre_doc_id from prepare_doc pd
left join pre_doc_item pdm on pd.pre_doc_id=pdm.pre_doc_id group by pd.pre_doc_id

原文地址:http://hudeyong926.iteye.com/blog/785188

EXPLAIN sql优化方法(3)DERIVED的更多相关文章

  1. EXPLAIN sql优化方法(2) Using temporary ; Using filesort

    优化GROUP BY语句   默认情况下,MySQL对所有GROUP BY col1,col2...的字段进行排序.这与在查询中指定ORDER BY col1,col2...类似.因此,如果显式包括一 ...

  2. EXPLAIN sql优化方法(1) 添加索引

    添加索引优化器更高效率地执行语句 假设我们有两个数据表t1和t2,每个有1000行,包含的值从1到1000.下面的查询查找出两个表中值相同的数据行: mysql> SELECT t1.i1, t ...

  3. DB-SQL-MySQL-杂项-调优:Mysql千万以上数据优化、SQL优化方法

    ylbtech-DB-SQL-MySQL-杂项-调优:Mysql千万以上数据优化.SQL优化方法 1.返回顶部 1. 1,单库表别太多,一般保持在200以下为宜 2,尽量避免SQL中出现运算,例如se ...

  4. sql优化方法学习和总结

    首先要问自己几个问题: 哪些类型的sql会散发出坏味道? sql优化的基本原理是什么,为什么有的sql快有的慢? sql优化和底层的存储引擎关系大么? 怎么看执行过程? 优化建议 1. 缓存查询,sq ...

  5. mysql索引sql优化方法、步骤和经验

    MySQL索引原理及慢查询优化 http://blog.jobbole.com/86594/ 细说mysql索引 https://www.cnblogs.com/chenshishuo/p/50300 ...

  6. 常见SQL优化方法

    SQL优化的一些方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否 ...

  7. sql优化方法

    1. SELECT子句中避免使用 “*” 当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用‘*’是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解析 ...

  8. 【数据库】SQL优化方法汇总

    最近在研究SQL语句的优化问题. 下面是从网上搜集的,有的地方有点老了,可是还是有很多可以借鉴的地方的. 如何加快查询速度? 1.升级硬件. 2.根据查询条件,建立索引,优化索引.优化访问方式,限制结 ...

  9. 大数据量高并发访问SQL优化方法

    保证在实现功能的基础上,尽量减少对数据库的访问次数:通过搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担:能够分开的操作尽量分开处理,提高每次的响应速度:在数据窗口使用SQL时,尽量把 ...

随机推荐

  1. Red Hat Linux分辨率调整

    在/etc/X11下手动产生xorg.conf文件, # vi /etc/X11/xorg.conf 文件中内容如下: ##Add the following codes: Section " ...

  2. C 中 main 函数的參数

          看到不同的人写出的 C 或者 C++ 程序时,可能会出现不一样的 main 函数的定义,以下的几种定义方式都是对的: int main(void) int main(int argc) i ...

  3. 一张游览PHP内核迷宫的藏宝图

    PHP内核就像一个迷宫,假设没有一个纵览全局的图,仅仅是面对当中的一个点,就会像进了迷宫一样,走着走着就走到了死胡同.在这个迷宫里转悠了非常久之后,近期得到了一张PHP藏宝图.然后看着这张图去游览PH ...

  4. 2-1 Restful中HTTP协议介绍

    Restful是一种基于资源的软件架构风格,所以从定义上来说是跟HTTP无关的.但是本课程提到的Restful API是基于HTTP协议的一种实现.所有相关知识都是基于现有的HTTP协议而来,并没有对 ...

  5. [.Net] Excel导入导出各种方式分析

    1.引言 1.1解决哪些问题   现在很多公司用的导出基本上采用的通过gridView导出excel,此种导出存在以下几种问题 1.数据量大的时候有时导出有时会让浏览器卡死,因为导出的excel不是真 ...

  6. 如何将本地代码上传到Github

    这些内容只是Git知识的冰山一角 更多知识请 阅读 Pro git.Pro git 所有内容均根据知识共享署名非商业性共享3.0版许可证授权,各位可以免费下载阅读,有pdf.mobi.qpub格式可以 ...

  7. 文档控件NTKO OFFICE 详细使用说明之预览Excel文件(查看、编辑、保存回服务器)

    1.在线预览Excel文件 (1) 运行环境 ① 浏览器:支持IE7-IE11(平台版本还支持Chrome和Firefox) ② IE工具栏-Internet 选项:将www.ntko.com加入到浏 ...

  8. Android java处理保留小数点后几位

    方式一: 四舍五入  double   f   =   111231.5585;  BigDecimal   b   =   new   BigDecimal(f);  double   f1   = ...

  9. java函数式编程之lambda表达式

    作为比较老牌的面向对象的编程语言java,在对函数式编程的支持上一直不温不火. 认为面向对象式编程就应该纯粹的面向对象,于是经常看到这样的写法:如果你想写一个方法,那么就必须把它放到一个类里面,然后n ...

  10. associatedtype关联类型

    associatedtype关联类型   定义一个协议时,有的时候声明一个或多个关联类型作为协议定义的一部分将会非常有用.关联类型为协议中的某个类型提供了一个占位名(或者说别名),其代表的实际类型在协 ...