mysql语句优化怎么用 mysql 语句优化

怎么进行mysql数据库优化?有八个方面可以对mysql进行优化mysql语句优化怎么用:
1、选取最适用的字段属性
MySQL可以很好的支持大数据量的存取mysql语句优化怎么用,但是一般说来mysql语句优化怎么用,数据库中的表越?。谒厦嬷葱械牟檠簿突嵩娇?。因此,在创建表的时候,为mysql语句优化怎么用了获得更好的性能,我们可以将表中字段的宽度设得尽可能小 。
2. 使用连接(JOIN)来代替子查询(Sub-Queries)
MySQL从4.1开始支持SQL的子查询 。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中 。
3、使用联合(UNION)来代替手动创建的临时表
MySQL从4.0的版本开始支持union查询,它可以把需要使用临时表的两条或更多的select查询合并的一个查询中 。在客户端的查询会话结束的时候,临时表会被自动删除 , 从而保证数据库整齐、高效 。
4、事务
尽管我们可以使用子查询(Sub-Queries)、连接(JOIN)和联合(UNION)来创建各种各样的查询,但不是所有的数据库操作都可以只用一条或少数几条SQL语句就可以完成的 。更多的时候是需要用到一系列的语句来完成某种工作 。但是在这种情况下 , 当这个语句块中的某一条语句运行出错的时候,整个语句块的操作就会变得不确定起来 。设想一下,要把某个数据同时插入两个相关联的表中,可能会出现这样的情况mysql语句优化怎么用:第一个表中成功更新后,数据库突然出现意外状况,造成第二个表中的操作没有完成,这样,就会造成数据的不完整,甚至会破坏数据库中的数据 。要避免这种情况,就应该使用事务,它的作用是:要么语句块中每条语句都操作成功,要么都失败
5、锁定表
尽管事务是维护数据库完整性的一个非常好的方法,但却因为它的独占性,有时会影响数据库的性能,尤其是在很大的应用系统中 。由于在事务执行的过程中,数据库将会被锁定,因此其它的用户请求只能暂时等待直到该事务结束 。其实,有些情况下我们可以通过锁定表的方法来获得更好的性能 。
6、使用外键
锁定表的方法可以维护数据的完整性,但是它却不能保证数据的关联性 。这个时候我们就可以使用外键 。
7、使用索引
索引是提高数据库性能的常用方法 , 它可以令数据库服务器以比没有索引快得多的速度检索特定的行 , 尤其是在查询语句当中包含有MAX(),MIN()和ORDERBY这些命令的时候 , 性能提高更为明显 。
8、优化的查询语句
绝大多数情况下,使用索引可以提高查询的速度 , 但如果SQL语句使用不恰当的话,索引将无法发挥它应有的作用 。
mysql怎么优化,都要怎么做mysql优化是一个大方向,大的是要分布式、读写分离,小的是对sql语句进行优化 。不过大多问的也是对sql语句优化,网上很多资料 , 我就大体说说 。
1、explain 索引 。
在你要查询的语句前加explain,看下有没有用到索引 , 如果出现type为all的,则说明有必要添加下索引 。(附多表查询速度比较:表关联existsin)慢查询优化是一大块 。
2、预统计 。
很经常需要对历史的数据进行过滤统计 。比如移动需要统计上个月电话小时数超过N小时的人,那么如果直接取原始数据 , 那将很慢,此时如果每天晚上凌晨都对数据进行预统计,统计每个人每天电话时数,那再来过滤就很快 。
3、分表分区 。
分表分区也是为了提高搜索速度 。例如,公交车的gps行驶记录,gps每隔15s报一次,一辆车一天运行12小时,一天就要插入4*60*12条记录,N辆车就要再乘,其数量极大 , 所以经常按月分表,分表里再按上报时间做日分区,这样就达到很大的优化,想查询某段时间,mysql很快就可以定位到 。
4、表结构 。
表结构很重要,经常需要多表关联查询一些字段 , 有时可以冗余下放到同一张表 。
mysql优化很有意思,多去查阅些资料 , 多去尝试,对你有好处的 。
mysql查询优化器应该怎么使用在开始演示之前,我们先介绍下两个概念 。
概念一,数据的可选择性基数,也就是常说的cardinality值 。
查询优化器在生成各种执行计划之前,得先从统计信息中取得相关数据,这样才能估算每步操作所涉及到的记录数,而这个相关数据就是cardinality 。简单来说,就是每个值在每个字段中的唯一值分布状态 。
比如表t1有100行记录,其中一列为f1 。f1中唯一值的个数可以是100个 , 也可以是1个,当然也可以是1到100之间的任何一个数字 。这里唯一值越的多少,就是这个列的可选择基数 。
那看到这里我们就明白了,为什么要在基数高的字段上建立索引,而基数低的的字段建立索引反而没有全表扫描来的快 。当然这个只是一方面 , 至于更深入的探讨就不在我这篇探讨的范围了 。
概念二,关于HINT的使用 。
这里我来说下HINT是什么,在什么时候用 。
HINT简单来说就是在某些特定的场景下人工协助MySQL优化器的工作,使她生成最优的执行计划 。一般来说,优化器的执行计划都是最优化的 , 不过在某些特定场景下,执行计划可能不是最优化 。
【mysql语句优化怎么用 mysql 语句优化】比如:表t1经过大量的频繁更新操作 , (UPDATE,DELETE,INSERT),cardinality已经很不准确了,这时候刚好执行了一条SQL,那么有可能这条SQL的执行计划就不是最优的 。为什么说有可能呢?
来看下具体演示
譬如,以下两条SQL ,
A:
select * from t1 where f1 = 20;
B:
select * from t1 where f1 = 30;
如果f1的值刚好频繁更新的值为30,并且没有达到MySQL自动更新cardinality值的临界值或者说用户设置了手动更新又或者用户减少了sample page等等 , 那么对这两条语句来说,可能不准确的就是B了 。
这里顺带说下 , MySQL提供了自动更新和手动更新表cardinality值的方法,因篇幅有限,需要的可以查阅手册 。
那回到正题上,MySQL 8.0 带来了几个HINT , 我今天就举个index_merge的例子 。
示例表结构:
mysql desc t1; ------------ -------------- ------ ----- --------- ---------------- | Field| Type| Null | Key | Default | Extra| ------------ -------------- ------ ----- --------- ---------------- | id| int(11)| NO| PRI | NULL| auto_increment || rank1| int(11)| YES| MUL | NULL||| rank2| int(11)| YES| MUL | NULL||| log_time| datetime| YES| MUL | NULL||| prefix_uid | varchar(100) | YES|| NULL||| desc1| text| YES|| NULL||| rank3| int(11)| YES| MUL | NULL|| ------------ -------------- ------ ----- --------- ---------------- 7 rows in set (0.00 sec)
表记录数:
mysql select count(*) from t1; ---------- | count(*) | ---------- |32768 | ---------- 1 row in set (0.01 sec)
这里我们两条经典的SQL:
SQL C:
select * from t1 where rank1 = 1 or rank2 = 2 or rank3 = 2;
SQL D:
select * from t1 where rank1 =100and rank2 =100and rank3 =100;
表t1实际上在rank1,rank2,rank3三列上分别有一个二级索引 。
那我们来看SQL C的查询计划 。
显然,没有用到任何索引 , 扫描的行数为32034 , cost为3243.65 。
mysql explainformat=json select * from t1where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: {"query_block": {"select_id": 1,"cost_info": {"query_cost": "3243.65"},"table": {"table_name": "t1","access_type": "ALL","possible_keys": ["idx_rank1","idx_rank2","idx_rank3"],"rows_examined_per_scan": 32034,"rows_produced_per_join": 115,"filtered": "0.36","cost_info": {"read_cost": "3232.07","eval_cost": "11.58","prefix_cost": "3243.65","data_read_per_join": "49K"},"used_columns": ["id","rank1","rank2","log_time","prefix_uid","desc1","rank3"],"attached_condition": "((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))"}}}1 row in set, 1 warning (0.00 sec)
我们加上hint给相同的查询,再次看看查询计划 。
这个时候用到了index_merge,union了三个列 。扫描的行数为1103 , cost为441.09 , 明显比之前的快了好几倍 。
mysql explainformat=json select /*index_merge(t1) */ * from t1where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: {"query_block": {"select_id": 1,"cost_info": {"query_cost": "441.09"},"table": {"table_name": "t1","access_type": "index_merge","possible_keys": ["idx_rank1","idx_rank2","idx_rank3"],"key": "union(idx_rank1,idx_rank2,idx_rank3)","key_length": "5,5,5","rows_examined_per_scan": 1103,"rows_produced_per_join": 1103,"filtered": "100.00","cost_info": {"read_cost": "330.79","eval_cost": "110.30","prefix_cost": "441.09","data_read_per_join": "473K"},"used_columns": ["id","rank1","rank2","log_time","prefix_uid","desc1","rank3"],"attached_condition": "((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))"}}}1 row in set, 1 warning (0.00 sec)
我们再看下SQL D的计划:
不加HINT ,
mysql explain format=json select * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: {"query_block": {"select_id": 1,"cost_info": {"query_cost": "534.34"},"table": {"table_name": "t1","access_type": "ref","possible_keys": ["idx_rank1","idx_rank2","idx_rank3"],"key": "idx_rank1","used_key_parts": ["rank1"],"key_length": "5","ref": ["const"],"rows_examined_per_scan": 555,"rows_produced_per_join": 0,"filtered": "0.07","cost_info": {"read_cost": "478.84","eval_cost": "0.04","prefix_cost": "534.34","data_read_per_join": "176"},"used_columns": ["id","rank1","rank2","log_time","prefix_uid","desc1","rank3"],"attached_condition": "((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100))"}}}1 row in set, 1 warning (0.00 sec)
加了HINT,
mysql explain format=json select /*index_merge(t1)*/ * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: {"query_block": {"select_id": 1,"cost_info": {"query_cost": "5.23"},"table": {"table_name": "t1","access_type": "index_merge","possible_keys": ["idx_rank1","idx_rank2","idx_rank3"],"key": "intersect(idx_rank1,idx_rank2,idx_rank3)","key_length": "5,5,5","rows_examined_per_scan": 1,"rows_produced_per_join": 1,"filtered": "100.00","cost_info": {"read_cost": "5.13","eval_cost": "0.10","prefix_cost": "5.23","data_read_per_join": "440"},"used_columns": ["id","rank1","rank2","log_time","prefix_uid","desc1","rank3"],"attached_condition": "((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100) and (`ytt`.`t1`.`rank1` = 100))"}}}1 row in set, 1 warning (0.00 sec)
对比下以上两个 , 加了HINT的比不加HINT的cost小了100倍 。
总结下,就是说表的cardinality值影响这张的查询计划,如果这个值没有正常更新的话,就需要手工加HINT了 。相信MySQL未来的版本会带来更多的HINT 。
关于mysql语句优化怎么用和mysql 语句优化的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。

    推荐阅读