标签:逻辑 ast 表名 https 如何 blog factory concat_ws 本地
由于最近公司的sql 总是总是超时,所以进行sql 的优化
原s‘q‘l :
SELECT temp.*,tcc.customer_level customerLevel FROM ( SELECT id_car idCar, id_customer idCustomer, c.brand_id brandId, c.factory_id factoryId, c.series_id seriesId, c.year_id yearId, main_id mainId, NAME, sex, customer_source customerSource, customer_type customerType, company_name companyName, cell_phone cellPhone, birthday, car_no carNo, car_prefix carPrefix, vin, factory_year factoryYear, car_model carModel, car_model_short carModelShort, cm.id_own_org idOwnOrg, cm.creationtime, cm.creator, cm.modifier, cm.modifiedtime, m.points, m. LEVEL, c.car_type AS carType, c.car_category_id AS carCategoryId FROM tm_customer_car cm INNER JOIN tm_customer m ON cm.id_customer = m.pk_id AND m.is_del = 0 INNER JOIN tm_car c ON cm.id_car = c.pk_id AND c.is_del = 0 WHERE cm.id_own_org in ( CAST(‘10545511425563138989‘ as unsigned ) , CAST(‘10545511425563140093‘ as unsigned ) , CAST(‘10545511425563140621‘ as unsigned ) , CAST(‘10545511425563141565‘ as unsigned ) , CAST(‘10545511425563139362‘ as unsigned ) , CAST(‘10545511425563136430‘ as unsigned ) , CAST(‘10545511425563138387‘ as unsigned ) , CAST(‘10545511425563137867‘ as unsigned ) , CAST(‘10545511425563139144‘ as unsigned ) , CAST(‘10545511425563139602‘ as unsigned ) , CAST(‘10545511425563128134‘ as unsigned ) , CAST(‘10545511425563140397‘ as unsigned ) , CAST(‘10545511425563137692‘ as unsigned ) , CAST(‘10545511425563140988‘ as unsigned ) , CAST(‘10545511425563138546‘ as unsigned ) , CAST(‘10545511425563139830‘ as unsigned ) , CAST(‘10545511425563136673‘ as unsigned ) , CAST(‘10545511425563138073‘ as unsigned ) , CAST(‘10545511425563137152‘ as unsigned ) , CAST(‘10545511425563138802‘ as unsigned ) , CAST(‘10545511425563137450‘ as unsigned ) , CAST(‘10545511425563135631‘ as unsigned ) , CAST(‘10545511425563136936‘ as unsigned ) ) and c.car_type = ‘0‘ and CONCAT_WS("",m.name,m.mnemonic,m.cell_Phone,c.car_prefix,c.car_no,c.contact_name,c.contact_cellphone,c.vin) like "%"‘28B0X‘"%" ORDER BY cm.id_customer DESC Limit 0, 10 ) AS temp LEFT JOIN tm_customer_config tcc ON temp. LEVEL = tcc.pk_id;
执行计划:
对表c 进行了全表查询是导致sql 的根本原因;
其实在表中已经对其中的列加了索引,但因为的最优选择而没使用,同一个sql 在本地和生产的服务器上的执行计划是不一样的,这也验证了我下面的结论;
我尝试了各种方法:
tm_customer_car id_customer,id_own_org 都已经有索引;
给 tm_car car_type列加索引意义不大; 列的值唯一性太小 --》放弃;
而给like 里的字段加索引,因为这边用的是 ‘%like%’ , 不会使用索引–》放弃;
对 tm_customer tm_car 选进行is_del 的select ,查询时间没怎么变化--》放弃。
最总在我们架构师的提醒下发现其实只要将where 的提交提前查询就好了,这样就可以使用已经建立的索引;
优化后的执行计划
INNER JOIN tm_car c ON cm.id_car = c.pk_id AND c.is_del = 0 AND c.id_own_org IN ( CAST( ‘10545511425563138989‘ AS UNSIGNED ), CAST( ‘10545511425563140093‘ AS UNSIGNED ), CAST( ‘10545511425563140621‘ AS UNSIGNED ), CAST( ‘10545511425563141565‘ AS UNSIGNED ), CAST( ‘10545511425563139362‘ AS UNSIGNED ), CAST( ‘10545511425563136430‘ AS UNSIGNED ), CAST( ‘10545511425563138387‘ AS UNSIGNED ), CAST( ‘10545511425563137867‘ AS UNSIGNED ), CAST( ‘10545511425563139144‘ AS UNSIGNED ), CAST( ‘10545511425563139602‘ AS UNSIGNED ), CAST( ‘10545511425563128134‘ AS UNSIGNED ), CAST( ‘10545511425563140397‘ AS UNSIGNED ), CAST( ‘10545511425563137692‘ AS UNSIGNED ), CAST( ‘10545511425563140988‘ AS UNSIGNED ), CAST( ‘10545511425563138546‘ AS UNSIGNED ), CAST( ‘10545511425563139830‘ AS UNSIGNED ), CAST( ‘10545511425563136673‘ AS UNSIGNED ), CAST( ‘10545511425563138073‘ AS UNSIGNED ), CAST( ‘10545511425563137152‘ AS UNSIGNED ), CAST( ‘10545511425563138802‘ AS UNSIGNED ), CAST( ‘10545511425563137450‘ AS UNSIGNED ), CAST( ‘10545511425563135631‘ AS UNSIGNED ), CAST( ‘10545511425563136936‘ AS UNSIGNED ) ) AND c.car_type = ‘0‘
总结:
1.执行计划不一致问题:
同一个SQL语句 会由于表的数据(量、和值个数不同等)变化而执行不同的执行计划,因为随着表的数据(量、和值个数不同等)变化,执行同一个执行计划的代价也在变化。
同一个SQL语句 选择 一个执行计划的依据:
表 统计信息 由此计算出 不同的执行计划的代价 由此选代价小的执行计划
表 的统计信息 一定要反映表当前的数据情况,否则选出的执行计划实际上不是代价最小那个,此时就要优化了,重新更新下表 的统计信息;
2.执行计划的解读
id
|
select_type
|
table
|
type
|
extra
|
---|---|---|---|---|
sql从里向外执行,通过以上观察发现 sql是按照id从大到小执行的。 |
1)、SIMPLE(不使用UNION或子查询等) 2) 、PRIMARY:最外层的select 3)、DERIVED:派生表的SELECT(FROM子句的子查询) 4)、UNION:UNION中的第二个或后面的SELECT语句 5)、UNION RESULT:UNION的结果。 6)、DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询 7)、SUBQUERY:子查询中的第一个SELECT 8)、DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询 |
有时不是真实的表名字, 看到的是derivedx(x是个数字,我的理解是第几步执行的结果) |
效率最高的是system,然后依次是 const、eq_ref、ref、range、index和 All。 一般来说,得保证查询至少达到range级别, 最好能达到ref,否则就可能会出现性能问题。 |
Using filesort
看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行
Using index
列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候
Using temporary
看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上
|
参考:
常见的优化方式:
标签:逻辑 ast 表名 https 如何 blog factory concat_ws 本地
原文地址:http://www.cnblogs.com/gcyinsist/p/7647586.html