准备空的tb_box表
函数
编写存储过程,给tb_box表添加100万条数据
修改关联数据
好于
优于
在执行以下语句时会报错:
前面在 https://www.jianshu.com/p/95e50fd017ea 文章中有提到这个问题,是直接修改sql_mode将 ONLY_FULL_GROUP_BY直接干掉。但是在《高性能mysql》中有一段话是这样的:
那么既然指出不要直接修改 sql_mode,那么我们应该如何让冲突的GRUOPBY语句正确执行呢?
文中有提到,可以使用max()和min()函数来实现;但是这种方式使用max和min函数较真的人可能会说这样写的分组查询有问题,确实如此。但是如果更加在乎查询效率,这样做也无可厚非。
如果,实在无法接受使用上面那种方式的话,可以这样使用子查询的方式来进行查询:
书上对于这种方式有描述如下:
这样写更满足关系理论,但是成本有点高,因为子查询需要填充临时表,而子查询中创建的临时表是没有任何索引的。
作者认为这样写对性能有影响。
但是从我测得结果来看,子查询的耗时反而更少。性能反而更佳。这个子查询耗时0.4秒。而使用max方式耗时0.8秒。几乎一倍。我的mysql版本是 5.7.22-log
为了解其中的原因,我们查看它的执行计划:
可见,因为子查询而产生了一层 DERIVED 临时表,但是这个临时表的Extra字段有显示 Using index、key里面显示自建索引。说明用到了索引。这是查询性能可观的一个重要原因吧;
另外我分别使用 SHOW PROFILE命令查看各部分耗时,对比之下。没看到有哪部分耗时差别特别大,使用JOIN、MAX 耗时比上子查询耗时都差不多是1倍
有些时候对一没有建立索引的字段,进行GRUOP BY时。会产生Using filesort 文件内排序。因为GRUOP BY是在排序的基础上进行分组的。
如下面sql:
如果业务上不对排序有要求。那么就可以禁止GRUOP BY的排序:
这样就把Using filesort给干掉了! 执行时间 1.237
当然,多数情况是多排序有要求的。此时也可以在GRUOP BY后面使用DESC和ASC关键字,使分组的结果集按需要的方向排序。如下:
分组查询的一个变种就是要求mysql对分组结果再进行一次超级聚合。可以使用GROUP BY WITH ROLLUP 来实现这种逻辑,但可能性能不佳。因为通过查询计划分析出它是使用 Using temporaryUsing filesort 来实现的。
使用WITH ROLLUP,查询时间2.531秒。不使用0.774 秒。
1、所以,很多时候。我们在应用程序中做超级聚合是最好的!
2、当然也可使用UNION ALL 来实现:
3、还可以通过FROM子句嵌套使用子查询:
数据库作为应用开发中必不缺少的基础设施,其性能直接影响应用的整体运行速度。MySQL是目前最广泛使用的关系型数据库之一,对于开发人员写出性能良好的SQL是必备的基本技能之一。下面简单描述下编写SQL的注意事项。
编写高质量的SQL需要从以下几个方面注意,基本原则、表字段注意事项、索引使用注意事项、SQL注意事项。
基本原则
一、尽量不要在数据库里做运算。如果遇到运算尽可能在应用程序层进行计算。
二、控制数据库表数量、控制单表数据量、控制表的字段数。建议单库不要超过四百张表,建议单表字段不要超过五十个,建议单表的数据量不要超过一千万。
三、不要编写大SQL、不要使用大事务。SQL尽量写的简单点拒绝编写大SQL,可以将大SQL拆分成多个小SQL,在应用层聚合。大事务拆分成多个小事务,快速提交。
表字段注意事项
一、选择合适数值字段类型。能用小字段类型的就用小字段类型,如tinyint就比int(1)在表示小数据时合适。
二、能用数字表示就不要用字符。如可以用无符号INT存储IP而不是字符串表示。
三、避免使用NULL字段。原因NULL字段查询优化难,含NULL复合索引失效。
四、少用或拆分TEXT/BLOB字段。字段太大需要更多的空间,性能低下,如需使用拆分到单独表。
五、不要在表字段中存储图片。
索引使用注意事项
一、合理添加索引。索引添加太多会影响更新速度。能够使用复合索引的避免加多个单独索引。
二、字符字段建立前缀索引。
三、不在索引列做运算。索引列做运算会导致索引失效。
四、尽量不使用外建。
SQL类注意事项
一、 SQL语句尽可能简单。大SQL拆分成多个小SQL。
二、事务编写尽量短小。事务即开即用用完立即关闭。
三、尽量不要使用select *。只取需要的列。
四、改写OR为IN或者改写为UNION *** 作。OR在数据量大的时候性能低于IN。
五、避免NOT、!=、>、NOT IN、NOT EXISTS、NOT LIKE等查询。
六、避免%前缀模糊查询。
七、能用UNION ALL不要用UNION。
八、GROUP BY中去除排序。自带排序。
九、同类型的字段做比较。字符类和字符类比较,数值类和数值类比较,不要混在一起比较。
十、尽量单表查询,尽量不要多表关联查询。多表关联查询可以拆分成单表查询在应用程序中聚合数据。
十一、复合索引的多列注意最左原则。
上述注意事项能避免很多性能低下的SQL,希望在开发过程中能引起注意。
很多时候,我们查询数据的时候都不会把明细数据查询出来,那样一般意义也不大。更多的时候是根据业务需求,把数据聚合成业务能直接使用的数据。MYSQL中有5个聚合函数,如下面5个,用的最多的还是count和sum,下面分别介绍一下用法。
【COUNT】
在MySQL中,COUNT()函数统计数据表中包含的记录行的总数,或者根据查询结果返回列中包含的数据行数,使用方法有以下两种:
求order表中,查询一共有多少条订单数,SQL语句如下↓
【SUM】
在MySQL中,SUM()是一个求总和的函数,返回指定列值的总和。
求order表中所有产品销售数量,SQL语句如下↓
【AVG】
在MySQL中,AVG()函数通过计算返回的行数和每一行数据的和,求得指定列数据的平均值。
求order表中,2021年所有产品的平均单价,SQL语句如下↓
【MAX/MIN】
在MySQL中,MAX()函数是用来返回指定列中的最大值。
求order表中,查询最大的单价价格,SQL预计如下↓
在MySQL中,MIN()函数是用来返回指定列中的最小值。
求order表中,查询最小的单价价格,SQL预计如下↓
【结合GROUP BY】
正常情况下,聚合函数都是搭配着GROUP BY来使用的。可以是按省份聚合、产品聚合、时间聚合等等。下面演示每个品牌最低单价的聚合,其他几个聚合函数使用方式一样,SQL语句如下↓
还可以用ORDER BY排个序,求每个品牌累计销售价格的SQL语句,从高到低排序↓
End
◆ PowerBI开场白
◆ Python高德地图可视化
◆ Python不规则条形图
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)