友情链接: http://enmotech.com/web/classify/43.html http://enmotech.com/web/classify/28.html 事件背景: SELECT * FROM girls WHERE age BETWEEN 18 and 24 and boyfriend='no'; 上周在朋友圈看到一张照片,随手转发并且提出了一个问题。
面试题一枚可好:请问以下SQL有什么可能的逻辑问题、语法问题、性能问题,可以怎样进行索引优化、逻辑优化以提升性能?
这个问题在朋友圈引起了很多朋友的兴趣,转发并且提问,希望有一个标准答案输出作为参考。
标准答案没有,但是我可以说说我的看法,当然前提是『这个SQL中的一切都是可以质疑的』。管中窥豹,博方家一笑。
去掉 boyfriend ='no' ,你懂的 (这位是老司机)
boyfriend 的名字叫 no 就尴尬了(这个直追 Null 那个梗)
有朋友还要加几个条件 and cost < 2000 RMB and beautiful > 85分 and height > 165 order by cost,beautiful desc,height desc (我不得不表示,孩子,你还是嫩啊);
用 boyfriend is NULL (这是技术流)
那么如何去检查核定数据字典的信息,如何确保SQL的性能,及时发现和解决问题?云和恩墨的自动化巡检诊断平台 - Bethune 正可以帮助你自动发现数据库中安全隐患,参考:
免费的白求恩自动巡检平台助你数据库平安
。
将 between and 改写成 >= 和 <= ,这会减少Oracle自己的转换,同时减少了SQL字符长度,缩减了网络传输,Shared Pool占用;
可以将 between and 改写成 IN (18,19 .. 24 ),数据库会将 In 值列表转换成几个等值比较,然后 CONCATENATION,其成本通常更低;
其次,这个表可能不是很小,而是很大,因为可能 boys 已经被分离出去,所以这个表应当考虑分区,辅助其他条件,通过分区剪裁快速缩减查询结果。 所以有朋友建议的SQL是这个样子的:
SELECT * FROM girls WHERE (age between 18 and 24) and NOT EXISTS (SELECT * FROM boys WHERE girls.boyfriend_id = boys.boyfriend_id);
再次,有朋友建议的索引优化:对 age 加 bitmap 索引,开并行。
注意,bitmap 对于这个频繁变更的表不是一个好选择,鉴于我们的判断,boyfriend = 'no' 的记录数极少,那么关于 age + boyfriend 的复合索引就能快速的找到记录,如果你是乐观主义者,就加个 rownum 的限制,如果你是一个悲观主义者,那么就可以去掉boyfriend字段,然后加个 rownum 的限制。
最后,其实我们很容易发现对于age和boyfriend的存储,行存不如列式存储,如果使用
Oracle 12c的IN-Memory
,在内存中进行列式压缩,可以极大的提高查询性能。
如果您非常关注数据库的性能,那么云和恩墨的数据库性能监控平台,将会让您对数据库的性能一目了然,及时预警。
参考:
洞若观火,ZONE助力性能提升
。
可是注意,以上我们的推断,是基于Oracle数据库的考虑,如果数据库是 MySQL、Redis,或是其他产品,该如何去调整和优化呢?
如果是MySQL,是否数据量相当庞大之后,如何分库分表?
那么多数据库,那么多管理、监控和优化工作,你一定要关注一下云和恩墨最新推出的 zCloud 云管平台,让多云、多数据管理、优化,融为一体,何以解多数据库管理之忧?唯有zCloud。
那么我还可以告诉你,如果完成以上查询,并且碰巧获得了输出,那么你可能已经违反了欧盟的GDPR法案,涉嫌侵犯了用户隐私(哈哈哈哈哈哈,开心吗)。
在2018年5月25日正式生效的 GDPR 法案,对于用户的隐私做出了严格的界定,如果侵犯滥用用户隐私信息,将遭遇高达2000万欧元或企业年营业额4%的高额惩罚,
注意最后一条保护的隐私内容:
公民基本的身份信息,如姓名、地址和身份证号等; 网络数据,如位置、IP地址、Cookie数据和RFID标签等; 医疗保健 和 遗传数据; 生物识别数据,如指纹、虹膜等; 种族或民族数据; 政治观点; 性取向;
参考前文:
GDPR 法案带来的思考
。所以对于企业数据的管理者,如何保护数据安全,确保用户隐私不被任意访问,不被DBA不授权访问,都是一个值得重视的问题,云和恩墨已经提供针对 GDPR 的安全增强解决方案,欢迎垂询。
千言万语,千头万绪,汇成最后的答案:这条SQL最终不应该被执行,也不会有返回结果。
加油吧,少年!
