Mariadb 马里亚布:武力“;选择直线“U形连接”;作为默认参数
我目前正在将数据从Percona 5.5.14迁移到MariaDB 10.1.22 在使用某些联接的特定查询上,两个版本的查询计划不同,响应时间>400ms 我发现解决这个问题的唯一方法是使用直线连接选项: Percona 5.5.14=>150ms MariaDB 10.1.22=>550ms==>150ms,带直线连接选项 我的问题是:是否有一个参数可以在使用联接的每个SELECT查询上强制使用STRIGHT_联接选项 我知道这不是一个好的解决方案,但我想知道它是否存在,因为我还没有找到它Mariadb 马里亚布:武力“;选择直线“U形连接”;作为默认参数,mariadb,percona,Mariadb,Percona,我目前正在将数据从Percona 5.5.14迁移到MariaDB 10.1.22 在使用某些联接的特定查询上,两个版本的查询计划不同,响应时间>400ms 我发现解决这个问题的唯一方法是使用直线连接选项: Percona 5.5.14=>150ms MariaDB 10.1.22=>550ms==>150ms,带直线连接选项 我的问题是:是否有一个参数可以在使用联接的每个SELECT查询上强制使用STRIGHT_联接选项 我知道这不是一个好的解决方案,但我想知道它是否存在,因为我还没有找到它
查询是在存储过程中调用的:
SELECT
C.NAME AS out_Name,
RC.ID AS out_PlanId,
ISO.A3 AS out_A3,
ISO.NAME AS out_CountryName,
ISO.NUMBER AS out_countryNumber,
C.ID AS out_CId,
RC.NAME AS out_CName,
RSG.NAME AS out_ServiceGroupName,
SPE.id AS out_EntryId,
SPE.GOUPID AS out_GroupId,
ZPE.ZONEID AS out_zoneId,
Z.NAME AS out_zoneName,
ZPE.ID AS out_zoneEntryId,
ZPE.PREFIX AS out_zonePrefix,
RC.PLANID AS out_zonePlanId,
SPE.ZONEID AS out_zoneGroupId,
ZSG.NAME AS out_zoneGroupName,
SCPA.ID AS out_scpAId,
SCPA.NAME AS out_scpAName,
ZG.ID AS out_zoningpId,
ZG.NAME AS out_zoningName,
IFNULL(SF1.NAME,"") AS out_Flag_serviceType_name,
IFNULL(SF2.NAME,"") AS out_Flag_service_name,
IFNULL(SF3.NAME,"") AS out_Flag_zone_name,
IFNULL(SF4.NAME,"") AS out_Flag_Plan_name,
RC.RULEID AS out_ruleId,
RP.NAME AS out_ruleName
FROM
table1 AS M ,
table2 AS C,
table3 AS RC,
table3 AS RP,
table4 AS SPE LEFT JOIN table12 AS SF2 ON SF2.id=SPE.FLAGID,
table5 AS ST LEFT JOIN table11 AS SF1 ON SF1.id=ST.FLAGID,
table6 AS RSG,
table7 AS ZSG,
table8 AS ZPE LEFT JOIN table14 as SF4 on SF4.id=ZPE.FLAGID,
table9 AS ISO,
table10 AS NP,
table11 AS Z LEFT JOIN table13 as SF3 on SF3.id=Z.FLAGID ,
table12 AS SCPA,
table13 AS ZG
WHERE
M.name ='TSL'
AND C.mvno_id =M.id
AND C.id ='1010'
AND RC.id =C.ID
AND RP.id =RC.RULEID
AND SPE.SERVICEID =RC.SERVICEID
AND RSG.ID =SPE.GOUP_ID
AND ST.NAME ='GOR'
AND SPE.SERVICETYPE_ID =ST.ID
AND ZSG.ID =SPE.ZONEID
AND ZPE.ZONE_PLAN_ID =RC.PLANID
AND NP.NAME ='OSI'
AND ZPE.NUMBERINGPLAN_ID =NP.ID
AND ZPE.ISOCOUNTRY_ID =ISO.ID
AND ZPE.ZONEID =ZSG.ID
AND Z.ID =ZPE.ZONEID
AND SCPA.ID =Z.ACTIONID
AND ZG.ID =Z.GROUPID
AND ZSG.ID =ZPE.ZONEID
AND UNIX_TIMESTAMP()
BETWEEN UNIX_TIMESTAMP(IFNULL(ZPE.VALIDFROM,0))
AND UNIX_TIMESTAMP(IFNULL(ZPE.VALIDUNTIL,"2038-01-01") )
AND (
(
'0'=0
AND ZPE.PREFIX ='AUT'
)
OR
( '0'=1
AND
(
substring('AUT',1,1)=ZPE.prefix
OR substring('AUT',1,2)=ZPE.prefix
OR substring('AUT',1,3)=ZPE.prefix
OR substring('AUT',1,4)=ZPE.prefix
OR substring('AUT',1,5)=ZPE.prefix
OR substring('AUT',1,6)=ZPE.prefix
OR substring('AUT',1,7)=ZPE.prefix
OR substring('AUT',1,8)=ZPE.prefix
OR substring('AUT',1,9)=ZPE.prefix
OR substring('AUT',1,10)=ZPE.prefix
OR substring('AUT',1,11)=ZPE.prefix
OR substring('AUT',1,12)=ZPE.prefix
OR substring('AUT',1,13)=ZPE.prefix
OR substring('AUT',1,14)=ZPE.prefix
OR substring('AUT',1,15)=ZPE.prefix
OR concat('AUT','#') =ZPE.prefix
)
)
)
ORDER BY LENGTH(prefix) DESC
LIMIT 1;
在
左连接周围加上括号
,以确保两个版本对其进行了正确的分析:
( table4 AS SPE LEFT JOIN table12 AS SF2 ON SF2.id=SPE.FLAGID ),
( table5 AS ST LEFT JOIN table11 AS SF1 ON SF1.id=ST.FLAGID ),
同时,将连接
从“commajoin”更改为连接。。在
上。这将使它更容易阅读。特别是,要清楚地显示中的内容
因为您显然是在生成SQL,所以要更加努力地避免像'0'=1
这样的构造
是不是substring('AUT',1,1)=ZPE.prefix或substring('AUT',1,2)=ZPE.prefix或…
更简单地写为ZPE.prefix=left('AUT',CHAR_LENGTH(ZPE.prefix
)?一旦对其进行了更改,您可能会进一步简化该表达式,可能会去掉
或
的另一面,并且可能会允许索引(前缀)`变得有用
请注意LENGTH()
是字节长度CHAR\u LENGTH()
是字符长度
您所有的id
都是BIGINT
?你真的需要那么大的射程吗?缩小数据类型将有助于提高性能
我使用intersect查看。请提供SHOW CREATE TABLE
ZPE`以便我们查看发生了什么。通常,这种优化不如拥有一个“综合”指数
我知道我没有回答你问的问题。但我宁愿先进行上述清理。我认为没有办法自动SJ。您是否愿意向我们展示其中一个查询,再加上解释
(最好在两台服务器上)和显示创建表
。也许还有其他方法可以恢复速度。谢谢你的回复。作为参考,它是一个循环中的存储过程调用(x100)