基于规则的查询改写方式主要包括子查询相关改写、外联接消除、 简化条件改写和 非 SPJ(SELECT PROJECT JOIN)的改写等。
子查询相关改写
优化器对于子查询一般使用嵌套执行的方式,也就是父查询每生成一行数据后,都需要执行一次子查询。使用这种方式需要多次执行子查询,执行效率很低。对于子查询的优化方式,一般会将其改写为联接操作,可大大提高执行效率,主要优点如下:
子查询改写的方式主要包括视图合并、子查询展开和将 ANY/ALL 使用 MAX/MIN 改写等。
视图合并
视图合并是指将代表一个视图的子查询合并到包含该视图的查询中,视图合并后,有助于优化器增加联接顺序的选择、访问路径的选择以及进一步做其他改写操作,从而选择更优的执行计划。
OceanBase 数据库支持对 SPJ 视图进行合并。如下示例为 Q1 改写为 Q2:
obclient>CREATE TABLE t1 (c1 INT, c2 INT);Query OK, 0 rows affected (0.00 sec)obclient>CREATE TABLE t2 (c1 INT PRIMARY KEY, c2 INT);Query OK, 0 rows affected (0.00 sec)obclient>CREATE TABLE t3 (c1 INT PRIMARY KEY, c2 INT);Query OK, 0 rows affected (0.00 sec)Q1:obclient>SELECT t1.c1, v.c1FROM t1, (SELECT t2.c1, t3.c2FROM t2, t3WHERE t2.c1 = t3.c1) vWHERE t1.c2 = v.c2;<==>Q2:obclient>SELECT t1.c1, t2.c1FROM t1, t2, t3WHERE t2.c1 = t3.c1 AND t1.c2 = t3.c2;
如果 Q1 不进行改写,则其联接顺序有以下几种:
进行视图合并改写后,可选择的联接顺序有:
可以看出,进行视图合并后,联接顺序可选择空间增加。对于复杂查询,视图合并后,对路径的选择和可改写的空间均会增大,从而使得优化器可生成更优的计划。
子查询展开
子查询展开是指将 WHERE 条件中子查询提升到父查询中,并作为联接条件与父查询并列进行展开。转换后子查询将不存在,外层父查询中会变成多表联接。
这样改写的好处是优化器在进行路径选择、联接方法和联接排序时都会考虑到子查询中的表,从而可以获得更优的执行计划。涉及的子查询表达式一般有 NOT IN、IN、NOT EXIST、EXIST、ANY、ALL。
子查询展开的方式如下:
ANY/ALL 使用 MAX/MIN 改写
对于 ANY/ALL 的子查询,如果子查询中没有 GROUP BY 子句、聚集函数以及 HAVING 时,以下表达式可以使用聚集函数 MIN/MAX 进行等价转换,其中为单独列且有非 NULL 属性:
val > ALL(SELECT col_item ...)<==> val > ALL(SELECT MAX(col_item) ...);val >= ALL(SELECT col_item ...) <==> val >= ALL(SELECT MAX(col_item) ...);val < ALL(SELECT col_item ...)<==> val < ALL(SELECT MIN(col_item) ...);val <= ALL(SELECT col_item ...) <==> val <= ALL(SELECT MIN(col_item) ...);val > ANY(SELECT col_item ...)<==> val > ANY(SELECT MIN(col_item) ...);val >= ANY(SELECT col_item ...) <==> val >= ANY(SELECT MIN(col_item) ...);val < ANY(SELECT col_item ...)<==> val < ANY(SELECT MAX(col_item) ...);val <= ANY(SELECT col_item ...) <==> val <= ANY(SELECT MAX(col_item) ...);
将子查询更改为含有 MAX/MIN 的子查询后,再结合使用 MAX/MIN 的改写,可减少改写前对内表的多次扫描,如下例所示:
obclient>SELECT c1 FROM t1 WHERE c1 > ANY(SELECT c1 FROM t2);<==>obclient>SELECT c1 FROM t1 WHERE c1 > ANY(SELECT MIN(c1) FROM t2);
结合 MAX/MIN 的改写后,可利用 t2.c1 的主键序将 LIMIT 1 直接下压到 TABLE Scan,将 MIN 值输出,执行计划如下:
obclient>EXPLAIN SELECT c1 FROM t1 WHERE c1 > ANY(SELECT c1 FROM t2)\G;*************************** 1. row ***************************Query Plan: ===================================================|ID|OPERATOR|NAME|EST. ROWS|COST|---------------------------------------------------|0 |SUBPLAN FILTER||1|73||1 | TABLE SCAN|t1|1|37||2 | SCALAR GROUP BY||1|37||3 |SUBPLAN SCAN|subquery_table|1|37||4 |TABLE SCAN|t2|1|36|===================================================Outputs & filters:-------------------------------------0 - output([t1.c1]), filter([t1.c1 > ANY(subquery(1))]),exec_params_(nil), onetime_exprs_(nil), init_plan_idxs_([1])1 - output([t1.c1]), filter(nil),access([t1.c1]), partitions(p0)2 - output([T_FUN_MIN(subquery_table.c1)]), filter(nil),group(nil), agg_func([T_FUN_MIN(subquery_table.c1)])3 - output([subquery_table.c1]), filter(nil),access([subquery_table.c1])4 - output([t2.c1]), filter(nil),access([t2.c1]), partitions(p0),limit(1), offset(nil)
外联接消除
外联接操作可分为左外联接、右外联接和全外联接。在联接过程中,由于外联接左右顺序不能变换,优化器对联接顺序的选择会受到限制。外联接消除是指将外联接转换成内联接,从而可以提供更多可选择的联接路径,供优化器考虑。
如果进行外联接消除,需要存在“空值拒绝条件”,即在 WHERE 条件中存在,当内表生成的值为 NULL 时,输出为 FALSE 的条件。
如下例所示:
obclient>SELECT t1.c1, t2.c2 FROM t1 LEFT JOIN t2 ON t1.c2 = t2.c2;
这是一个外联接,在其输出行中 t2.c2 可能为 NULL。如果加上一个条件,则通过该条件过滤后,t2.c1 输出不可能为 NULL, 从而可以将外联接转换为内联接。
obclient>SELECT t1.c1, t2.c2 FROM t1 LEFT JOIN t2 ON t1.c2 = t2.c2 WHERE t2.c2 > 5;<==>obclient>SELECT t1.c1, t2.c2 FROM t1 LEFT INNER JOIN t2 ON t1.c2 = t2.c2WHERE t2.c2 > 5;
简化条件改写
HAVING 条件消除
如果查询中没有聚集操作及 GROUP BY,则 HAVING 可以合并到 WHERE 条件中,并将 HAVING 条件删除, 从而可以将 HAVING 条件在 WHERE 条件中统一管理,并进行进一步相关优化。
obclient>SELECT * FROM t1, t2 WHERE t1.c1 = t2.c1 HAVING t1.c2 > 1;<==>obclient>SELECT * FROM t1, t2 WHERE t1.c1 = t2.c1 AND t1.c2 > 1;
改写后计划如下例所示,条件被下压到了 TABLE SCAN 层。
obclient>EXPLAIN SELECT * FROM t1, t2 WHERE t1.c1 = t2.c1 HAVING t1.c2 > 1\G;*************************** 1. row ***************************Query Plan:=========================================|ID|OPERATOR|NAME|EST. ROWS|COST|-----------------------------------------|0 |NESTED-LOOP JOIN||1|59||1 | TABLE SCAN|t1|1|37||2 | TABLE GET|t2|1|36|=========================================Outputs & filters:-------------------------------------0 - output([t1.c1], [t1.c2], [t2.c1], [t2.c2]), filter(nil),conds(nil), nl_params_([t1.c1])1 - output([t1.c1], [t1.c2]), filter([t1.c2 > 1]),access([t1.c1], [t1.c2]), partitions(p0)2 - output([t2.c1], [t2.c2]), filter(nil),access([t2.c1], [t2.c2]), partitions(p0)
等价关系推导
等价关系推导是指利用比较操作符的传递性,推倒出新的条件表达式,从而减少需要处理的行数或者选择到更有效的索引。
OceanBase 数据库可对等值联接进行推导,比如可以推导出
a = b AND a > 1 AND b > 1
, 如果 b 上有索引,且在该索引选择率很低,则可以大大提升访问 b 列所在表的性能。
如下例所示,条件
t1.c1 = t2.c2 AND t1.c1 > 2
,等价推导后为
t1.c1 = t2.c2 AND t1.c1 > 2 AND t2.c2 > 2
,从计划中可以看到 t2.c2 已下压到 TABLE SCAN,并且使用 t2.c2 对应的索引。
obclient>CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT);Query OK, 0 rows affected (0.15 sec)obclient>CREATE TABLE t2(c1 INT PRIMARY KEY, c2 INT, c3 INT, KEY IDX_c2(c2));Query OK, 0 rows affected (0.10 sec)/*此命令需运行于 MySQL 模式下*/obclient>EXPLAIN EXTENDED_NOADDR SELECT t1.c1, t2.c2 FROM t1, t2WHERE t1.c1 = t2.c2 AND t1.c1 > 2\G;*************************** 1. row ***************************Query Plan:==========================================|ID|OPERATOR|NAME|EST. ROWS|COST|------------------------------------------|0 |MERGE JOIN ||5|78||1 | TABLE SCAN|t2(IDX_c2)|5|37||2 | TABLE SCAN|t1|3|37|==========================================Outputs & filters:-------------------------------------0 - output([t1.c1], [t2.c2]), filter(nil),equal_conds([t1.c1 = t2.c2]), other_conds(nil)1 - output([t2.c2]), filter(nil),access([t2.c2]), partitions(p0),is_index_back=false,range_key([t2.c2], [t2.c1]), range(2,MAX ; MAX,MAX),range_cond([t2.c2 > 2])2 - output([t1.c1]), filter(nil),access([t1.c1]), partitions(p0),is_index_back=false,range_key([t1.c1]), range(2 ; MAX),range_cond([t1.c1 > 2])
恒真/假消除
对于如下恒真恒假条件可以进行消除:
如下例所示,对于
WHERE 0 > 1 AND c1 = 3
,由于使得 AND 恒假, 所以该 SQL 不用执行,可直接返回,从而加快查询的执行。
obclient>EXPLAIN EXTENDED_NOADDR SELECT * FROM t1 WHERE 0 > 1 AND c1 = 3\G;*************************** 1. row ***************************Query Plan:===================================|ID|OPERATOR|NAME|EST. ROWS|COST|-----------------------------------|0 |TABLE SCAN|t1|0|38|===================================Outputs & filters:-------------------------------------0 - output([t1.c1], [t1.c2]), filter([0], [t1.c1 = 3]), startup_filter([0]),access([t1.c1], [t1.c2]), partitions(p0),is_index_back=false, filter_before_indexback[false,false],range_key([t1.__pk_increment], [t1.__pk_cluster_id], [t1.__pk_partition_id]),range(MAX,MAX,MAX ; MIN,MIN,MIN)always false
非 SPJ 的改写
冗余排序消除
冗余排序消除是指删除 order item 中不需要的项,减少排序开销。以下三种情况可进行排序消除:
LIMIT 下压
LIMIT 下压改写是指将 LIMIT 下降到子查询中,OceanBase 数据库现在支持在不改变语义的情况下,将 LIMIT 下压到视图(示例 1)及 UNION 对应子查询(示例 2)中。
示例 1:
obclient>SELECT * FROM (SELECT * FROM t1 ORDER BY c1) a LIMIT 1;<==>obclient>SELECT * FROM (SELECT * FROM t1 ORDER BY c1 LIMIT 1) a LIMIT 1;
示例 2:

obclient>(SELECT c1,c2 FROM t1) UNION ALL (SELECT c3,c4 FROM t2) LIMIT 5;<==>obclient>(SELECT c1,c2 FROM t1 LIMIT 5) UNION ALL (SELECT c3,c4 FROM t2 limit 5) LIMIT 5;
DISTINCT 消除
MIN/MAX 改写
有谁能推荐下itunes最新的比较有用的软件?
iPad(iPhone)好用的20个应用软件(Apps)所有的苹果的“软件”在iPad都可运行,使用“2X”可以放大,但图像质量不好。 只有专门为iPad开发的软件,其中有的质量高,好用。 如:Stanza--最佳中文书书籍下载、阅读软件(可连接中文书网站)。 Zinio--可在线浏览、购买美国杂志。 bing--微软的浏览器。 Wikipanion--wiki百科查询软件。 凤凰网--新闻电视节目,运行很好。 Goodreader(0.99$)文件的WiFi传输、阅读、txt改写,功能很多。 FileApp--各种文件的WiFi传输、阅读。 免费,文件数目无限制。 QuickVoice--多功能录音软件。 AlarmClockwithTunesFree-多功能闹钟。 AccuWeather--全球气候预报。 Skype(2x)--适时通话、会议。 WorldFactBooks-世界各国简况。 XECurrencyforiPad--对180多种货币进行换算。 eyewitness--英国,每日提供高分辨照片。 很精彩。 Proteced--个人照片库,可放幻灯,密码保护。 Operation---简单函数计算器。 QuickGraph--函数作图。 EMDPTE--元素周期表,性能数据。 SpeedtestHD--WiFi测量网速。 MagnetMeter--模拟的指南针、磁强计、加速度计。
Word办公软件技巧有哪些?
Word办公软件技巧汇总三招去掉页眉那条横线1、在页眉中,在“格式”-“边框和底纹”中设置表格和边框为“无”,应用于“段落” 2、同上,只是把边框的颜色设置为白色(其实并没有删的,只是看起来没有了) 3、在“样式”栏里把“页眉”换成“正文”就行了,会多出--(两个横杠) 这是用户不愿看到的,又要多出一步作删除-- 解决方法:替换时在前引号前加上一个空格 问题就解决了格式刷的使用1、设定好文本1的格式。 2、将光标放在文本1处。 3、单击格式刷按钮。 4、选定其它文字(文本2),则文本2的格式与文本1 一样。 若在第3步中单击改为双击,则格式刷可无限次使用,直到再次单击格式刷(或按Esc键)为止。 删除网上下载资料的换行符(象这种“↓”)在查找框内输入半角^l(是英文状态下的小写L不是数字1),在替换框内不输任何内容,单击全部替换,就把大量换行符删掉啦。 让Word表格快速一分为二将光标定位在分开的表格某个位置上,按下“Ctrl+Shift+Enter”组合键。 这时你就会发现表格中间自动插入一个空行,这样就达到了将一个表格一分为二的目的。 用Word来拆字首先点击“工具/自定义 /命令/分解图片”,按住鼠标左键把它拖放到工具栏任意位置即可;然后点击“插入/图片/艺术字”,例如输入空心字“心”,选择该“心”字剪切,在选择性粘贴中选图片(Windows图元文件),选中该字,点击工具栏中的“分解图片”按钮,这样可以选择“心”中的任意笔画进行一笔一画的拆分了。 快速删除段前段后的任意多个空格选定这些段段落,单击居中按钮,然后再单击原来的那种对齐方式按钮(如果原来是居中对齐的,先单击其它对齐方式按钮,再单击居中按钮就行了),是不是这些空格全不见了?快速换页的方法双击某页的右下脚,光标即可定位在那里,然后按回车直到换页。 ctrl+回车点插入按纽,分隔符,选中分页符,然后确认就OK了。 表格的简单调整宽度鼠标放在表格的右边框上带鼠标变成可以调整大小的时候 双击 根据表格内的内容调节表格大小代替金山词霸点工具——语言——翻译,在右边出现的搜索框中输入要查的单词,回车就可以翻译了。 可以选择英语翻成中文或中文翻成英语。 第一次使用可能要安装。 [Alt]键实现标尺的精确定位如果你经常使用水平标尺来精确定位标签、页边框、首字缩进及页面对象的位置,那么你点击标尺设置页边框或标签时,您只可以将其设置为1字符或2字符,但不能设为1.5字符!要想设置更为精确的度量单位(例如百分之几字符),在按住[Alt]键的同时,点击并移动标尺或边框,此时标尺将用数字精确显示出当前的位置为百分之几字符位置。 用“记事本”去除格式网页上COPY下来的东西往往都是有网格的,如果直接粘贴在WORD中会杂乱无章。 先粘贴到记事本当中,再粘贴到WORD中,就可以去除网格等格式,再全选选择清除格式,居中再取消居中即可取消所有格式。 可以直接在WORD中进行:(菜单)编辑/选择性粘贴……/无格式文本/确定。 将阿拉伯数字转换成中文数字或序号1、先输入阿拉伯数字(如1234),全选中,单击“插入/数字/数字类型(壹、贰……)/确定”,即变为大写数字(如壹仟贰佰叁拾肆),会计朋友非常适用。 2、其他像一千二百三十四,甲、乙……,子、丑……,罗马数字等的转换,可参考上法。 如何输入双横线等在WORD中输入三个等号然后回车,出来的是双横线。 同样的方法也可以做出波浪线单横线哦!~~~~~ , ###为中间粗上下细的三线, ***为点线, ~~~为波浪线, ---为单线输入拼音字母的音调怎么输入用智能ABC,键入v9,然后自己挑选吧!页码设置1、打开页眉/页脚视图,点击插入页码按钮,将页码插入(此时所有的页码是连续编号的) 2、切换到页面视图,在需要从1计数的页面上插入连续分节符(插入--分隔符--分节符--连续) 3、再次换到页眉/页脚视图,点击设置页码格式按钮,将页码编排-起始页码设置为1把Excel中的表格以图片形式复制到Word中除了用抓图软件和全屏拷贝法外还有更简单的呢 先选定区域,按住Shift健点击编辑会出现复制图片粘贴图片,复制了后,在Word中选粘贴图片就可像处理图片一样处理Excel表格了!快速调整页眉横线长度在word插入页眉后,会自动在此位置添加一条长横线。 如果需要调整此线的长度及其水平位置,可以首先激活页眉,选择格式下的段落命令,调整一下左右缩进的字符值,确定可以看到最终效果了!WORD 中如何输入分数1、打开word,点击工具菜单栏的“插入”,在下拉菜单中点“域”。 2、在打开的复选框中的类别栏中“选等式公式”,域名中“EQ”。 然后点击“选项”,在出现的菜单选项中选“F(,)”,接着点击“添加到域”并“确定”。 3、然后在输入F(,)数字,如要输入23 只需在F(,)输入F(2,3)就能得到2/3怎样使WORD 文档只有第一页没有页眉,页脚页面设置-页眉和页脚,选首页不同,然后选中首页页眉中的小箭头,格式-边框和底纹,选择无,这个只要在“视图”——“页眉页脚”,其中的页面设置里,不要整个文档,就可以看到一个“同前”的标志,不选,前后的设置情况就不同了Word中双击鼠标的妙用在Word的程序窗口中不同位置上双击,可以快速实现一些常用功能,我们归纳如下:在标题栏或垂直滚动条下端空白区域双击,则窗口在最大化和原来状态之间切换; 将鼠标在标题栏最左边WORD文档标记符号处双击,则直接退出WORD(如果没有保存,会弹出提示保存对话框); 将鼠标移到垂直滚动条的上端成双向拖拉箭头时双击,则快速将文档窗口一分为二; 将鼠标移到两个窗口的分界线处成双向拖拉箭头时双击,则取消对窗口的拆分; 在状态栏上的“修订”上双击,则启动“修订”功能,并打开“审阅”工具栏。 再次双击,则关闭该功能,但“审阅”工具栏不会被关闭; 在状态栏上的“改写”上双击,则转换为“改写”形式(再次“双击”,转换为“插入”形式); 如果文档添加了页眉(页脚),将鼠标移到页眉(页脚)处双击,则激活页眉(页脚)进入编辑状态,对其进行编辑;在空白文档处双击,则启动“即点即输”功能; 在标尺前端空白处双击,则启动“页面设置”对话框。 文本框的线条1. 制作好文档后,通过“视图→页眉页脚”命令,调出“页眉页脚”工具栏,单击其中的“显示→隐藏文档正文文字”按钮,隐藏正文部分的文字内容。 2. 选择“插入”菜单中的“文本框”命令,在页眉的下方插入一个空文本框。 3. 在文本框内加入作为水印的文字、图形等内容,右击图片,选择快捷菜单中的“设置图片格式”命令,在对话框中“图片”选项卡下,通过“图像控制”改变图像的颜色,对比度和亮度,并手动调整图片的大小。 4. 通过“设置文本框格式”命令,把文本框的线条色改为无线条色。 5. 单击“页眉页脚”工具栏的“关闭”按钮,退出“页眉页脚”编辑。 每页添加水印的操作1. 制作好文档后,通过“视图→页眉页脚”命令,调出“页眉页脚”工具栏,单击其中的“显示→隐藏文档正文文字”按钮,隐藏正文部分的文字内容。 2. 选择“插入”菜单中的“文本框”命令,在页眉的下方插入一个空文本框。 3. 在文本框内加入作为水印的文字、图形等内容,右击图片,选择快捷菜单中的“设置图片格式”命令,在对话框中“图片”选项卡下,通过“图像控制”改变图像的颜色,对比度和亮度,并手动调整图片的大小。 4. 通过“设置文本框格式”命令,把文本框的线条色改为无线条色。 5. 单击“页眉页脚”工具栏的“关闭”按钮,退出“页眉页脚”编辑。 6. 完成上述步骤的操作,水印制作得以完成,这样就为每一页都添加了相同的水印。 Word双面打印技巧我们平时用电脑的时候可能都少不了打印材料,Word是我们平常用的最多的Office软件之一。 有时我们要用Word打印许多页的文档,出于格式要求或为了节省纸张,会进行双面打印。 我们一般常用的操作方法是:选择“打印”对话框底部的“打印”下拉列表框中的“打印奇数页”或“打印偶数页”,来实现双面打印。 我们设定为先打印奇数页。 等奇数页打印结束后,将原先已打印好的纸反过来重新放到打印机上,选择该设置的“打印偶数页”,单击“确定”按钮。 这样通过两次打印命令就可以实现双面打印。 我们也可以利用另一种更灵活的双面打印方式:打开“打印”对话框,选中“人工双面打印”,确定后就会出现一个“请将出纸器中已打印好的一面的纸取出并将其放回到送纸器中,然后‘确定’按键,继续打印”的对话框并开始打印奇数页,打完后将原先已打印好的纸反过来重新放到打印机上,然后按下该对话框的“确定”按键,Word就会自动再打印偶数页,这样只用一次打印命令就可以了。 两种方法对比,后者较前者更为方便。
请问如何写好武侠小说?具体需要什么步骤?
怎样才能写好武侠小说?梁羽生也表明了自己的观点,他说:“写好武侠小说并不容易,作者只有具备相当的历史、地理、民俗、宗教等等知识,并有相当的艺术手段、古文底子,而且还要懂得中国武术的三招两式,才能期望成功。 ”梁羽生认为,要写好武侠小说,撰写者的创作态度应当端正。 他在一九七七年应新加坡写作人协会的邀情作演讲时,介绍了自已创作武侠小说所作的努力:一是努力反映某一时代的历史真实;二是着力塑造人物的性格;三是力求加强作品的艺术感染力。 梁羽生虽然喜爱武侠小说,竭尽心智地创作武侠小说,并取得了很大的成就,但他对武侠小说的态度仍是明智的、公允的。 他曾对大陆一度兴起的盲目的泛滥的“武侠热”泼过冷水。 一九八五年,他借《文艺报》一隅表示自已的忧虑:“有的部门作了统计,至少有五十多家小报发表我和他人的武侠小说。 不少地方的一些报纸转载我的武侠小说,有的加以改写,都未经作者同意。 据说有的把两个回目合并成一个回目,甚至有的不是我写的武侠小说,却标上我的名字,以蒙骗读者。 我认为,反映现实生活的作品应当在文学园地占主要地位;但最近有些小报,从第一版到最后一版全部刊载我或其他作者的武侠小说,这样的路不是越走越窄了吗?”这表明了梁羽生的真知灼见。
发表评论