我今天反对一种新的查询优化问题。
我的查询是:
SELECT *
FROM sanrss
LEFT JOIN sanrum ON sanrum.sanrum___rforefide = sanrss.sanrss___rforefide AND sanrum.sanrum___rfovsnide = sanrss.sanrss___rfovsnide AND sanrum.sanrum___sanrsside = sanrss.sanrsside
LEFT JOIN sanact ON sanact.sanact___rforefide = sanrum.sanrum___rforefide AND sanact.sanact___rfovsnide = sanrum.sanrum___rfovsnide AND sanact.sanact___sanrsside = sanrum.sanrum___sanrsside AND sanact.sanact___sanrumide = sanrum.sanrumide AND sanact.sanact___sanrumide IS NOT NULL AND sanact.sanact___rsanopide='CCAM'
INNER JOIN saneds ON sanrss.sanrss___rforefide = saneds.saneds___rforefide AND sanrss.sanrss___rfovsnide = saneds.saneds___rfovsnide AND sanrss.sanrss___sanedside = saneds.sanedside
INNER JOIN sandia ON (sandia___rforefide, sandia___rfovsnide, sandia___sanrsside, sandia___sanrumide, sandiasig) = (sanrum___rforefide, sanrum___rfovsnide, sanrum___sanrsside, sanrumide, 1)
INNER JOIN rsaidp ON saneds.saneds___rforefide = rsaidp.rsaidp___rforefide AND saneds.saneds___rsaidpide = rsaidp.rsaidpide
WHERE sanrss.sanrss___rforefide = 'CHUL' AND sanrss.sanrss___rfovsnide = '201303_prov' AND sanrss.sanrssdtf >= '2013-01-01 00:00:00.0' AND sanrss.sanrssdtf <= '2013-03-31 23:59:59.999'
and sanrss.sanrsside = '7801512'
这不是真正的*,而是选择了 300 个字段。
在我们的一个服务器上它很慢,但在另一个服务器上却没有,所以我对其进行了解释以确定执行计划,这个给我的总运行时间为 0.5 毫秒!但是解释分析的实际总工作时间大约是 3.6 秒。
所以我试着只准备请求,这是一个意识到只有查询计划的计算是造成巨大延迟的原因。
我尝试切换 GEQO 的一些会话参数(努力 1,努力 10,GEQO 停用),对执行时间没有影响。对查询的所有表进行stats计算后,计算时间下降到2.4秒。
奇怪的是,在较慢的服务器(相同的 CPU 和主板,但没有 ssd 存储)上,具有相同参数的完全相同的查询只用了 15 毫秒来确定查询计划和执行。两台服务器之间的主要区别在于数据量,在所有表中存在问题的一台服务器中的数据量大约是两倍。
那么我应该考虑什么来理解是什么减慢了我的执行计划计算?