MySql优化子查询

  • 用子查询语句来影响子查询中产生结果rows的数量和顺序. For example:
  • SELECT * FROM t1 WHERE t1.column1 IN
      (SELECT column1 FROM t2 ORDER BY column1);
    SELECT * FROM t1 WHERE t1.column1 IN
      (SELECT DISTINCT column1 FROM t2);
    SELECT * FROM t1 WHERE EXISTS
      (SELECT * FROM t2 LIMIT 1);//limit关键字不在含有in关键字的子查询中(用exists代替)
  • 代替和子查询做join操作. For example:
    SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN (
      SELECT column1 FROM t2);

    代替:

    SELECT DISTINCT t1.column1 FROM t1, t2
      WHERE t1.column1 = t2.column1;
  • 一些子查询会被改写成join连接为了兼容不支持子查询的老版本.然而,在一些情况下改写子查询为join操作会提高性能 ;
  • 去掉在子查询中出现的外部语句. For example:
    SELECT * FROM t1
      WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);

    代替:

    SELECT * FROM t1
      WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);

    For another example:

    SELECT (SELECT column1 + 5 FROM t1) FROM t2;

    代替:

    SELECT (SELECT column1 FROM t1) + 5 FROM t2;
  • 用行子查询代替一个相关子查询. For example:
    SELECT * FROM t1
      WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);

    代替:

    SELECT * FROM t1
      WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1
                    AND t2.column2=t1.column2);
  • 用 NOT (a = ANY (...)) 代替 a <> ALL (...).
  • 用 x = ANY (table containing (1,2))代替 x=1 OR x=2.
  • 用 = ANY 代替 EXISTS.
  • 因为不相关的子查询通常返回一行结果, IN 通常慢于 =. For example:
    SELECT * FROM t1
      WHERE t1.col_name = (SELECT a FROM t2 WHERE b = some_const);

    代替:

    SELECT * FROM t1
      WHERE t1.col_name IN (SELECT a FROM t2 WHERE b = some_const);
  • MySQL 执行不相关的子查询一次. 用 explain确保一个子查询是真正的不相关的.
  • MySQL改写 INALLANY, and SOME 子查询尝试提高select的列在子查询中加索引的可能性 .
  • MySQL 代替用带Index查找功能,explain语句描述为一种特别的join(unqie subquery 或者index subquery)子查询(如下面形式):
    ... IN (SELECT indexed_column FROM single_table ...)
    
  • MySQL 增前了表达式(以下形式调用(min() or max()), 除非null值或者空集合:
    value {ALL|ANY|SOME} {> | < | >= | <=} (uncorrelated subquery)
    

    For example,:

    WHERE 5 > ALL (SELECT x FROM t)
  • 可能被优化成:WHERE 5 > (SELECT MAX(x) FROM t)
时间: 2024-10-08 11:49:47

MySql优化子查询的相关文章

mysql in 子查询 效率慢 优化(转)

现在的CMS系统.博客系统.BBS等都喜欢使用标签tag作交叉链接,因此我也尝鲜用了下.但用了后发现我想查询某个tag的文章列表时速度很慢,达到5秒之久!百思不解(后来终于解决),我的表结构是下面这样的,文章只有690篇. 文章表article(id,title,content)标签表tag(tid,tag_name)标签文章中间表article_tag(id,tag_id,article_id)其中有个标签的tid是135,我帮查询标签tid是135的文章列表用以下语句时发现速度好慢,我文章才

MySQL 表子查询

MySQL 表子查询 表子查询是指子查询返回的结果集是 N 行 N 列的一个表数据. MySQL 表子查询实例 下面是用于例子的两张原始数据表: article 表: aid title content uid 1 文章1 文章1正文内容... 1 2 文章2 文章2正文内容... 1 3 文章3 文章3正文内容... 2 4 文章4 文章4正文内容... 3 blog 表: bid title content uid 1 日志1 日志1正文内容... 1 2 文章2 文章2正文内容... 1

生产库中遇到mysql的子查询

使用过oracle或者其他关系数据库的DBA或者开发人员都有这样的经验,在子查询上都认为数据库已经做过优化,能够很好的选择驱动表执行,然后在把该经验移植到mysql数据库上,但是不幸的是,mysql在子查询的处理上有可能会让你大失所望,在我们的生产系统上就由于碰到了这个问题: select  i_id, sum(i_sell) as i_sell from table_data where i_id in (select i_id from table_data where Gmt_create

MySQL FROM 子查询

FROM 子句中的子查询 MySQL FROM 子查询是指 FROM 的子句作为子查询语句,主查询再到子查询结果中获取需要的数据.FROM 子查询语法如下: SELECT ... FROM (subquery) AS name ... 子查询会生成一个临时表,由于 FROM 子句中的每个表必须有一个名称,因此 AS name 是必须的.FROM 子查询也称为衍生数据表子查询. FROM 子查询实例 table1: s1 s2 1 5 2 12 3 20 FROM 子查询 SQL 如下: SELE

SQL优化-子查询&case&limit

load 导数据.notesdxtdb 数据库    total_time  475.60秒. 监控服务:仓颉 select t_.*, a.name acquirer_name,m.merchant_name, am.merchant_name acq_merchant_name,                   ag.name agency_name            from              (            select t.* ,               

Mysql 查询技巧:使用JOIN优化子查询

1.数据准备 mysql> select * from student; +----+--------+----------+---------+-------------+ | id | name   | idCardNo | isCadre | nickname    | +----+--------+----------+---------+-------------+ |  1 | Tom    | 350020   |       1 | Big T       | |  2 | Ji

MySQL 通过semi join 优化子查询

测试环境 mysql> desc class; +------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+-------+ | class_num | int(11) | NO | PRI | NULL | | | class_name |

mysql in子查询的优化

项目遇到一个MySQL查询特别慢的语句: SELECT * FROM ( SELECT DISTINCT t.vc_date, t.c_bankno, t.vc_bankacco, t.vc_moneytype, t.en_totalbala FROM tbankaccobala t WHERE 1 = 1 AND t.id IN ( -- 这个查询需要3s: SELECT SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY d_importtime DESC),

MySQL5.7性能优化系列(二)——SQL语句优化(3)——使用物化策略优化子查询

优化器使用物化策略(Materialization)来实现更有效的子查询处理.通过生成子查询结果作为临时表,通常在内存中,实现加速查询执行. MySQL首次需要子查询结果,将该结果实现为临时表.任何随后的结果都需要,MySQL再次指向临时表.优化器可以使用散列索引对表进行索引,以使查找更加快速和便宜.该索引是唯一的,它消除了重复,并使表格更小. 子查询实现可能时使用内存中临时表,如果表变得太大,则返回到磁盘存储. 如果不使用物化策略,则优化器有时将非相关子查询重写为相关子查询.例如,以下IN子查