mysql 语句优化一列

优化前语句:

SELECT

ifnull(s.mileage, -1) as mile,

s.fuel_hkm as val,

t.fhkm_rank as rank,

ifnull((select u.photo from app_user u where u.user_id = t.user_id  limit 1),‘‘) as path,

case when s.car_id = ‘***********‘ then 0

else 1 end as self,

ifnull((

SELECT

case

when ifnull(u.nickname, ‘‘) != ‘‘ then u.nickname

when ifnull(u.username, ‘‘) != ‘‘ then u.username

when ifnull(u.customer_number, ‘‘) != ‘‘ then u.customer_number

else u.mobile END as uname

FROM

app_user u

WHERE

u.user_id = t.user_id

LIMIT 1

),‘‘)  as manname,

ifnull((select case when ifnull(c.nickname,‘‘) != ‘‘ then c.nickname else REPLACE(c.lisence,SUBSTR(c.lisence,3,3),‘***‘) end from app_car c where c.car_id = t.car_id limit 1),‘‘)  as carname

FROM

app_car_sum_7daily s,

app_rank_ka t

WHERE

t.date = ‘2016-07-12‘

and t.date = s.date

and t.car_id = s.car_id

and s.fuel_hkm > 0

and t.fhkm_rank > 0

ORDER BY rank,self,convert(manname using gbk) limit 10

优化后语句:

select * from (

select

ifnull(s.mileage, -1) as mile,

s.fuel_hkm as val,

t.fhkm_rank as rank,

ifnull(u.photo,‘‘) as path,

case when s.car_id = ‘***********‘ then 0

else 1 end as self,

case

when ifnull(u.nickname,‘‘) != ‘‘ then u.nickname

when ifnull(u.username,‘‘) != ‘‘ then u.username

when ifnull(u.customer_number,‘‘) != ‘‘ then u.customer_number

else ifnull(u.mobile,‘‘) end as manname,

case

when ifnull(c.nickname,‘‘) != ‘‘ then c.nickname

else ifnull(REPLACE(c.lisence,SUBSTR(c.lisence,3,3),‘***‘),‘‘) end as carname

from

app_rank_ka t

join app_car_sum_7daily s on (s.date = t.date and s.car_id = t.car_id and s.fuel_hkm > 0)

join app_user u on (u.user_id = t.user_id)

join app_car c on (c.car_id = t.car_id)

where t.date = ‘2016-07-12‘ and t.fhkm_rank > 0

ORDER BY rank limit 200) a order by rank,self,convert(manname using gbk) limit 10;

优化方法:

1、去子查询优化为join查询

2、子查询带limit 1的表链接键都为主键,所以不再需要limit 1

3、app_rank_ka(t)表,对别名为rank的字段和date字段建联合索引优化内层排序idx_date_rank

4、在不对sql业务进行判断及变更的情况下采用折中的办法,先根据rank limit 200条或者觉得合适的条数只要不是非常多,再进行业务排序

5、嵌套链接索引都很合理,该点无优化空间

优化原理:

1、该sql慢的主要原因在于order by 多个字段

2、mysql的order by只是利用sort_buffer做第一个字段的排序,后面的字段会在临时表中进行,并且计算量很大,根据optimizer_trace跟踪本来只有4万多条数据在排序三个字段之后扫描了14万次以上才完成

3、mysql的order by优化算法有两个,一种sort_buffer存的数据为(sort_key1,sort_key2,sort_key3,row_id)排序完成还需回表查询数据,另一种为(sort_key1,sort_key2,sort_key3,key1 value,key2 value,key3 value....)包含所有需求字段数据,在数据不超过阈值(max_length_for_sort_data)时默认都会采用第二种优化方式

3、上面sql采用的方式就利用了索引先优化从表里面取数据时的排序,限制了200条作为外层的排序数据,不过这也建立了一个临时表,鉴于数据长度不是很大,在数据量不多时效率影响有限,在外层利用三个字段进行排序不管是使用那一种sort算法查找数据都是很高效的

4、关联子查询在mysql查询优化器中处理都不是很如意,优化为join不仅避免优化器选择的问题也可以降低优化器的消耗时间

优化前后执行时间对比:

优化前:

|        1 | 8.94656525 |

|        2 | 8.77086475 |

优化后:

|        3 | 0.00527075 |

|        4 | 0.00513025 |

该sql有5种order by排序规则的查询,优化方式相同!!!!!,分别建date和这5个字段建立联合索引,可以删除现有的date单列所以,因为date字段为时间列不会做更新操作,即使该5个字段经常更新页之间数据移动也不会发生页分裂的情况,又因为mysql提供change_buffer为辅助索引提供内存缓冲,所以新建(5-1)个索引的维护成本完全可以接受

PS:如果业务上能修改排序条件,可以只使用子查询就行,效率更高,通常尽量只使用一个字段排序,在数据量大时多字段的排序耗时成倍增长

时间: 2024-08-05 11:12:55

mysql 语句优化一列的相关文章

mysql语句优化总结(一)

Sql语句优化和索引 1.Innerjoin和左连接,右连接,子查询 A.     inner join内连接也叫等值连接是,left/rightjoin是外连接. SELECT A.id,A.name,B.id,B.name FROM A LEFT JOIN B ON A.id =B.id; SELECT A.id,A.name,B.id,B.name FROM A RIGHT JOIN ON B A.id= B.id; SELECT A.id,A.name,B.id,B.name FROM

mysql语句优化方案(网上流传)

关于mysql处理百万级以上的数据时如何提高其查询速度的方法 最近一段时间由于工作需要,开始关注针对Mysql数据库的select查询语句的相关优化方法. 由于在参与的实际项目中发现当mysql表的数据量达到百万级时,普通SQL查询效率呈直线下降,而且如果where中的查询条件较多时,其查询速度简直无法容忍.曾经测试对一个包含400多万条记录(有索引)的表执行一条条件查询,其查询时间竟然高达40几秒,相信这么高的查询延时,任何用户都会抓狂.因此如何提高sql语句查询效率,显得十分重要.以下是网上

9 MySQL语句优化的原则

1.使用索引来更快地遍历表. 缺省情况下建立的索引是非群集索引,但有时它并不是最佳的.在非群集索引下,数据在物理上随机存放在数据页上.合理的索引设计要建立在对各种查询的分析和预测上.一般来说:  a.有大量重复值.且经常有范围查询( > ,< ,> =,< =)和order by.group by发生的列,可考虑建立群集索引:  b.经常同时存取多列,且每列都含有重复值可考虑建立组合索引:  c.组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列.索引虽有助于提高性

MySQL语句优化的原则

1.使用索引来更快地遍历表. 缺省情况下建立的索引是非群集索引,但有时它并不是最佳的.在非群集索引下,数据在物理上随机存放在数据页上.合理的索引设计要建立在对各种查询的分析和预测上.一般来说: a.有大量重复值.且经常有范围查询( > ,< ,> =,< =)和order by.group by发生的列,可考虑建立群集索引: b.经常同时存取多列,且每列都含有重复值可考虑建立组合索引: c.组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列.索引虽有助于提高性能但不

mysql语句优化技巧

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引.2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=03.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引

MySQL语句优化方法(简单版)

基础回顾: sql语句是怎么样运行的? 一般来说,客户端发送sql语句到数据库服务器——数据库服务器进行运算并返回结果——客户端显示sql语句运行结果. 在本地运行时以workbench为例,客户端为workbench,数据库服务器则是安装在本地的mysql数据库. 为什么要优化sql语句? 加快运行速度 减少数据库资源开销 在企业级数据库中sql优化是必备技能. 基础优化技能: 在查询语句中尽量减少查询语句返回结果,尤其是 SELECT*FROMXXX 来返回全部数据.只选择必要的数据,作为返

MySQL语句优化

一.优化SQL的一般步骤 a)通过SHOW STATUS;命令了解各种SQL的执行频率 SHOW [SESSION|GLOBAL] STATUS; SESSION (默认)表示当前连接 GLOBAL 表示自数据库启动至今 SHOW GLOBAL STATUS LIKE 'com_%' b)查看本次登录以来增删改查的次数 SHOW STATUS LIKE 'com_select%' SHOW STATUS LIKE 'com_update%' SHOW STATUS LIKE 'com_inser

MySQL 语句大全--------添加列,修改列,删除列

ALTER TABLE:添加,修改,删除表的列,约束等表的定义. 查看列:desc 表名; 修改表名:alter table t_book rename to bbb; 添加列:alter table 表名 add column 列名 varchar(30); 删除列:alter table 表名 drop column 列名; 修改列名MySQL: alter table bbb change nnnnn hh int; 修改列名SQLServer:exec sp_rename't_stude

mysql 语句优化心得

排序导致性能较慢 优化策略:1.尽量不使用排序 2.只查有索引的结果然后 内连接查询 select  bizchance0_.*  from biz_chance bizchance0_, biz_bizcustomer bizbizcust1_ where bizchance0_.uuid=bizbizcust1_.recordinfoid and bizchance0_.ispublic=1          order by bizchance0_.orderkey desc limit