在开始介绍index merge/ROR优化之前,打算先介绍MySQL是如何对range/ref做成本评估的。MySQL是基于成本(cost)模型选择执行计划,在多个range,全表扫描,ref之间会选择成本最小的作为最终的执行计划。仍然强烈建议先阅读登博的slide:《查询优化浅析》,文中较为详细的介绍MySQL在range优化时成本的计算。
本文将继续介绍range/ref执行计划选择的一些不容忽略的细节。希望看客能够通过此文能够了解更多细节。 (more…)
登博开了一个头,希望能够往前走一点。泛读了整个MySQL Range优化的相关代码,这里将总结Range优化相关的数据结构。本文不是从宏观(High Level)角度介绍Range优化相关内容,如果看客对此感兴趣,建议绕过本文,直接阅读参考文献,相信会有收获。
已经连续写了几篇关于优化器相关的数据结构的博客了,只是希望需要的人是在需要的时候能够看到。
在开始介绍Range的主要数据结构之前,我们先看Range优化的一些概念和背景。依旧建议先阅读参考文件的[1-8],Sergey Petrunya写的PPT和文档质量都很高,很多图示,非常直观的展示了原理。
(1) 什么是Range条件? 参考Range Optimization@MySQL Manual 单列Range和多列Range
(2) 给定一个KEY(key1)对应的WHERE条件,如何将其转化成一个Range,下面是”简述”,详细参考单列Range:
SELECT * FROM t1 WHERE (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR (key1 < 'bar' AND nonkey = 4) OR (key1 < 'uux' AND key1 > 'z');
前篇介绍了MySQL存储索引信息的基本数据结构。本篇将延续下去,介绍MySQL如何找到可以使用的索引,以及期间需要使用的主要数据结构。
谁适合阅读: 本文不打算从High Level来介绍MySQL索引及其使用,相反是从MySQL源码对应的数据结构开始介绍。如果你了解MySQL索引的基本原理,还打算继续从源码的角度解决一些索引使用的问题,那么你适合参考本文,否则,打住,真的很枯燥:(。在可见的未来,作者还将介绍Range优化相关的数据结构等。
本文介绍MySQL如何发现WHERE条件中的等值表达式,并通过分析这些等值表达式,找到可以使用的索引。在这个过程中,MySQL将递归的访问所有WHERE条件”谓词”,并将等值表达式都存储到KEY_FIELD对象的数组中。
然后遍历该KEY_FIELD数组,并同时对比所有索引列,找到哪些字段是在索引列中出现,这些字段则可能可以使用索引,MySQL将所有这些字段都存储在对象KEYUSE数组中。
最后,对KEYUSE进行处理,包括排序、删除无法使用的索引列。这时KEYUSE数组就是所有可以使用REF的索引列了。 (more…)
·
天很暗,不知道是因为很晚了,还是要下大雨。路很窄,间隔铺着一块青石板的那种,走着遇到丁奇、褚霸,嘟囔了几句,不得要领,就回家了。到家里,准备坐下,发现房间被大米给淹了,于是拼命把大米拔开,找出椅子。门是关好的,努力拂开米粒的时候,抬头无意间发现有人隔着门上面的小玻璃窗朝里面窥,脸上露出着诡异的笑,仔细看,好像是武藏同学…
然后,就醒了…
梦倒没什么,不过后面的事情吓得我出了一身冷汗。
醒得时候大概四、五点,窗外正黑,人还很迷糊,感觉膀胱肿胀,于是迷迷糊糊起身去厕所。迷糊中穿好拖鞋,迷糊中尝试去摸索房门,大跨一步,怎么还没摸到门,心里嘀咕,再走一步,怎么还没有摸到房门!下意识,摸着墙继续向前走,继续摸索,怎么可能!还是没有房门!!
这时候心理已经感觉哪里不对了,有些慌,但是脑子还是很迟钝。这才想起睁开眼看看。睁开眼,前面一片漆黑(黎明前那种),再回头环顾四周,吓得我一身冷汗!!竟然不在自己的房间里!!这是哪儿? (more…)
很枯燥的,配首背景音乐吧:
本文将尝试介绍MySQL索引存储相关的数据结构。程序=数据结构+算法,了解数据结构,然后就可以进一步了解MySQL源码中如何使用索引,如何选择自己的执行计划。
MySQL使用TABLE对象来描述一个数据表,那么数据表的索引是如何描述,索引的统计信息又是如何存储的呢? 例如我们有如下数据表:
CREATE TABLE `users` ( `id` int(11) NOT NULL, `nick` varchar(32) DEFAULT NULL, `reg_date` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `IND_NICK` (`nick`), KEY `IND_REGDATE` (`reg_date`) )
该表有索引,PRIMARY KEY、IND_NICK、IND_REGDATE,我们来看看MySQL内部是如何存储这三个索引,以及如何使用这些索引的统计信息的。下图,描述了存储一个数据表索引的主要结构:
前篇介绍了MySQL如何从SQL语句转换成一个内部对象。本文是前篇的延续,将更加详细的介绍WHERE语句对应的Item对象。
(建议阅读:The Item Class@MySQL Internals Manual,忽略本小结)
MySQL Internals Manual较为详细的介绍了Item对象。Item对象经常被称作”thingamabob”( A thingamabob is a noun used to describe items that either you can’t remember the name of or that don’t actually exist.)。Item是一个类,每一个Item实例都:(1)代表一个SQL语句里的对象;(2)有取值;(3)有数据类型指针。
下面列出的的SQL相关的对象都是一个Item对象,或者继承至Item:(1)一段字符; (2)数据表的某列; (3)一个局部或全局变量; (4)一个存储过程的变量; (5) 一个用户参数; (6)一个函数/存储过程(这包括运算符+、||、=、like等) 。例如下面的SQL语句: (more…)