主頁 > 資料庫 > MySQL一個關于derived table的bug描述與規避

MySQL一個關于derived table的bug描述與規避

2023-06-22 08:09:19 資料庫

關聯文章:

  • MySQL對derived table的優化處理與使用限制

一、Bug描述

同事遇到一個有意思的陳述句,說一條SQL在MySQL8.0.25版本運行出的結果明顯與給定的where條件不符,而在8.0.26版本上是正常的,陳述句上加了一個無關的用戶變數后在8.0.25版本上結果才是正確的,想不通這是怎么回事,這么有意思的事情自然引起了我的興趣,借此機會深入了解了一下MySQL關于derived table的優化,為了方便演示效果,讓小伙伴們關注到現象的本質,我將陳述句進行了簡化處理,

下面是模擬的表結構與資料,

create table t1(id int,c1 varchar(100));

insert into t1 values(1,'gg張三');
insert into t1 values(2,'bb李四');
insert into t1 values(3,'cc王五');
insert into t1 values(4,'dd劉麻子');
insert into t1 values(1,'gg張三');
insert into t1 values(2,'bb李四');

SQL陳述句:

SELECT temp.type
  FROM (SELECT  SUBSTRING(t.type, 3) type
          FROM (SELECT distinct t1.c1 type
                  FROM test.t1
                 ORDER BY t1.c1) t) temp
 WHERE temp.type='張三'
 ORDER BY temp.type DESC;

在MySQL8.0.25版本的運行結果如下:

mysql> SELECT temp.type
    ->   FROM (SELECT  SUBSTRING(t.type, 3) type
    ->           FROM (SELECT distinct t1.c1 type
    ->                   FROM test.t1
    ->                  ORDER BY t1.c1) t) temp
    ->  WHERE temp.type='張三'
    ->  ORDER BY temp.type DESC;
+--------+
| type   |
+--------+
| 李四   |
+--------+
1 rows in set (0.01 sec)

在MySQL8.0.26版本的運行結果如下:

mysql> SELECT temp.type
    ->   FROM (SELECT  SUBSTRING(t.type, 3) type
    ->           FROM (SELECT distinct t1.c1 type
    ->                   FROM test.t1
    ->                  ORDER BY t1.c1) t) temp
    ->  WHERE temp.type='張三'
    ->  ORDER BY temp.type DESC;
+--------+
| type   |
+--------+
| 張三   |
+--------+
1 rows in set (0.00 sec)

很明顯,這個陳述句在8.0.25版本運行出的結果與我們給定where條件不符,我們要查詢關于“張三”的記錄,結果回傳的結果是”李四“的,很明顯的一個bug,但是到8.0.26版本這個問題得到了修正,

懷著對各版本對此陳述句執行情況的好奇,我先是往前追溯,查看了8.0.24,8.0.23,8.0.22,8.0.21,5.7.39版本上做了測驗,發現在8.0.24,8.0.23,8.0.22版本結果與8.0.25相同,都是錯誤結果,而在8.0.21版本上運行結果是正確的,5.7版本上結果也是正確的的,往后追溯,8.0.26,8.0.32版本也都是正確的,因此判斷此問題在8.0.22~8.0.25版本上存在此問題,

這個陳述句最大的特點就是運用了派生表(derived table),MySQL在8.0.22版本上引入了一個關于派生表的優化器開關derived_condition_pushdown, 默認設定為on,我們看一下關于這個特性在官方檔案中的描述:

MySQL 8.0.22 and later supports derived condition pushdown for eligible subqueries. For a query such as SELECT * FROM (SELECT i, j FROM t1) AS dt WHERE i > constant, it is possible in many cases to push the outer WHERE condition down to the derived table, in this case resulting in SELECT * FROM (SELECT i, j FROM t1 WHERE i > constant) AS dt.

在8.0.26版本中修復的bug中發現一個與此問題相關的bug,描述如下:

When a condition is pushed down to a materialized derived table, a clone of the derived table expression replaces the column (from the outer query block) in the condition. When the cloned item included a FULLTEXT function, it was added to the outer query block instead of the derived table query block, which led to problems. To fix this, we now use the derived query block to clone such items. (Bug #32820437)

看到這里我們可以確定,就是8.0.22版本時這個新特性的引入,導致了此問題的產生,慶幸的是這個問題在8.0.26版本中已得到解決

文章開頭說的問題陳述句跟這個bug的描述是吻合的,派生表temp外部的過濾條件 temp.type=’張三' 其實是substring(t.type,3)='張三',應該就是對應bug描述中的”the cloned item included a FULLTEXT function“不管substring函式是不是fulltext函式,總之這個問題伴隨著這個bug的修復也修復了,這種陳述句結構下,很多函式都有這個問題,比如trim,replace等,MySQL內部如何處理得到的錯誤結果我們就不去深究了,但是如何規避這個bug我們需要了解一下,

二、bug規避

升級到8.0.26及以上的版本問題自然就解決了,如果不想升級也是有很多方式來規避此問題的,這個bug的產生主要是因為新特性derived_condition_pushdown的引入,關閉此特性,在這幾個版本中就不會出現這個問題,

mysql> set optimizer_switch="derived_condition_pushdown=off";
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT temp.type
    ->   FROM (SELECT  SUBSTRING(t.type, 3) type
    ->           FROM (SELECT distinct t1.c1 type
    ->                   FROM test.t1
    ->                  ORDER BY t1.c1) t) temp
    ->  WHERE temp.type='張三'
    ->  ORDER BY temp.type DESC;
+--------+
| type   |
+--------+
| 張三   |
+--------+
1 rows in set (0.00 sec)

優化器開關里還有一個派生表相關的開關,就是derived_merge,是否進行派生表合并,關閉這個derived_merge,結果也是正確的,

mysql> set optimizer_switch="derived_merge=off,derived_condition_pushdown=on";
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT temp.type
    ->   FROM (SELECT  SUBSTRING(t.type, 3) type
    ->           FROM (SELECT distinct t1.c1 type
    ->                   FROM test.t1
    ->                  ORDER BY t1.c1) t) temp
    ->  WHERE temp.type='張三'
    ->  ORDER BY temp.type DESC;
+--------+
| type   |
+--------+
| 張三   |
+--------+
1 rows in set (0.00 sec)

也就是說當派生表條件下推撞上派生表合并時,資料庫做的處理不對,導致了問題的產生,

因此只要控制不發生合并,或者不發生條件下推,就能規避此bug,除了關閉優化器開關,在陳述句級別我們還有很多方式來規避,下面列舉幾個,

1.使用NO_MERGE的hint來阻止derived table合并,

SELECT  /*+ NO_MERGE(temp) */ temp.type
  FROM (SELECT substring(t.type,3) type
          FROM (SELECT distinct t1.c1 type
                  FROM test.t1
                 ORDER BY t1.c1) t
) temp
 WHERE temp.type='張三'
 ORDER BY temp.type DESC;

2.使用NO_DERIVED_CONDITION_PUSHDOWN的hint阻止條件下推,

SELECT  temp.type
  FROM (SELECT /*+ NO_DERIVED_CONDITION_PUSHDOWN(t) */ substring(t.type,3) type
          FROM (SELECT  distinct t1.c1 type
                  FROM test.t1
                 ORDER BY t1.c1) t
) temp
 WHERE temp.type='張三'
 ORDER BY temp.type DESC;

3.使用limit子句,能同時阻止合并與條件下推,

例如:

SELECT temp.type
  FROM (SELECT substring(t.type,3) type
          FROM (SELECT distinct t1.c1 type
                  FROM test.t1
                 ORDER BY t1.c1) t limit 100000000000) temp
 WHERE temp.type='張三'
 ORDER BY temp.type DESC;

4.分配用戶變數,阻止derived table 合并,

例如:

SELECT temp.type
  FROM (SELECT (@i:=0) as num, substring(t.type,3) type
          FROM (SELECT distinct t1.c1 type
                  FROM test.t1
                 ORDER BY t1.c1) t) temp
 WHERE temp.type='張三'
 ORDER BY temp.type DESC;

這種方式就是前文提到的,為什么加了一個與業務邏輯無關的用戶變數,結果就正確的原因,

5.使用union all來阻止derived table 合并

SELECT temp.type
  FROM (SELECT substring(t.type,3) type
          FROM (SELECT distinct t1.c1 type
                  FROM test.t1
                 ORDER BY t1.c1) t
                 union all 
                 select '1') temp
 WHERE temp.type='張三'
 ORDER BY temp.type DESC;

這些方法主要是依據優化器使用hint靈活控制優化器的開關,以及derive_merge與derived_condition_pushdown的使用限制,

三、總結

  1. MySQL8.0.22~MySQL8.0.25 因為優化器新特性derived_condition_pushdown帶來的bug,可以通過derived merge與 derived_condition_pushdown 的使用限制以及優化器開關hint來有效規避bug,當然升級到高版本更好,
  2. 如果想讓新特性derived_condition_pushdown發揮作用,就要避開它的使用限制,
  3. 一個新特性的出現,不可避免會伴隨著一些bug的產生,不要對此心存恐懼,只要深入了解它,就能取其長,避其短,

Enjoy GreatSQL ??

關于 GreatSQL

GreatSQL是由萬里資料庫維護的MySQL分支,專注于提升MGR可靠性及性能,支持InnoDB并行查詢特性,是適用于金融級應用的MySQL分支版本,

相關鏈接: GreatSQL社區 Gitee GitHub Bilibili

GreatSQL社區:

社區博客有獎征稿詳情:https://greatsql.cn/thread-100-1-1.html

image-20230105161905827

技術交流群:

微信:掃碼添加GreatSQL社區助手微信好友,發送驗證資訊加群

image-20221030163217640

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/555803.html

標籤:其他

上一篇:全球唯一云廠商!華為云高分入選2023Gartner Peer Insights?云資料庫管理系統“客戶之選”

下一篇:返回列表

標籤雲
其他(161479) Python(38244) JavaScript(25512) Java(18251) C(15238) 區塊鏈(8271) C#(7972) AI(7469) 爪哇(7425) MySQL(7265) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5875) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4606) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2436) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1984) HtmlCss(1971) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1881) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • MySQL一個關于derived table的bug描述與規避

    # 關聯文章: - [MySQL對derived table的優化處理與使用限制](http://mp.weixin.qq.com/s?__biz=MzkzMTIzMDgwMg==&mid=2247501528&idx=1&sn=03ea1cd0eb8f42bacda0583879ad494c&ch ......

    uj5u.com 2023-06-22 08:09:19 more
  • 全球唯一云廠商!華為云高分入選2023Gartner Peer Insights?云資料

    本文分享自華為云社區《華為云高分入選2023Gartner Peer Insights?云資料庫管理系統“客戶之選”》,作者:GaussDB 資料庫 。 近日,Gartner最新發布Gartner Peer Insights 《Voice of the Customer for Cloud Data ......

    uj5u.com 2023-06-22 08:08:51 more
  • MySQL 8的MGR集群中設定autocommit=0引起ERROR 1064 (42000)錯誤

    在一套MySQL MGR集群測驗環境中,同事測驗時,在my.cnf引數檔案中修改了autocommit引數(修改為autocommit=0),結果上周五,由于系統管理員要升級RHEL 8.8的系統補丁,所以將這這三臺MySQL的資料庫服務關閉了,升級完RHEL 8.8的系統補丁后,啟動MySQL的集 ......

    uj5u.com 2023-06-22 08:08:08 more
  • 穩,從資料庫連接池 testOnBorrow 看架構設計

    本文從 Commons DBCP testOnBorrow 的作用機制著手,管中窺豹,從一點去分析資料庫連接池獲取的程序以及架構分層設計。以下內容會按照每層的作用,貫穿分析整個呼叫流程。 ......

    uj5u.com 2023-06-22 08:08:05 more
  • InnoDB鎖初探(一):鎖分類和RR不同場景下的鎖機制

    # Mysql資料庫鎖(Innodb) 資料庫鎖是Mysql實作資料一致性的基礎之一,是在事務的基礎之上,基于Mysql Server層或存盤引擎層實作的。 ## 鎖日志 前置條件: ```sql set GLOBAL innodb_status_output=ON; set GLOBAL inno ......

    uj5u.com 2023-06-22 08:07:58 more
  • ClickHouse技術研究及語法簡介

    本文對Clickhouse架構原理、語法、性能特點做一定研究,同時將其與mysql、elasticsearch、tidb做橫向對比,并重點分析與mysql的語法差異,為有mysql遷移clickhouse場景需求的技術預研及參考。 ......

    uj5u.com 2023-06-22 08:07:50 more
  • MySQL一個關于derived table的bug描述與規避

    # 關聯文章: - [MySQL對derived table的優化處理與使用限制](http://mp.weixin.qq.com/s?__biz=MzkzMTIzMDgwMg==&mid=2247501528&idx=1&sn=03ea1cd0eb8f42bacda0583879ad494c&ch ......

    uj5u.com 2023-06-22 08:07:42 more
  • HiveSQL在使用聚合類函式的時候性能分析和優化詳解

    帶聚合函式的SQL邏輯,我們可以根據其執行程序的不同,將其分成三大類來進行分析:
    僅在Reduce階段聚合的SQL執行邏輯
    在Map和Reduce階段都有聚合操作的SQL執行邏輯
    高級分組聚合的執行SQL邏輯 ......

    uj5u.com 2023-06-22 08:07:24 more
  • 性能提升30%!袋鼠云數堆疊基于 Apache Hudi 的性能優化實戰決議

    Apache Hudi 是一款開源的[資料湖解決方案](https://www.dtstack.com/dtengine/easylake?src=https://www.cnblogs.com/DTinsight/p/szsm),它能夠幫助企業更好地管理和分析海量資料,支持高效的[資料更新和查詢](https://www.dtstack.com/dtengine/ea ......

    uj5u.com 2023-06-22 08:07:14 more
  • ClickHouse(14)ClickHouse合并樹MergeTree家族表引擎之Versioned

    [toc] >VersionedCollapsingMergeTree引擎繼承自MergeTree并將折疊行的邏輯添加到合并資料部分的演算法中。VersionedCollapsingMergeTree用于相同的目的折疊樹但使用不同的折疊演算法,允許以多個執行緒的任何順序插入資料。特別是,Version列有 ......

    uj5u.com 2023-06-22 08:07:07 more