Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL union优化为左连接,速度更快,但查询计划显示成本更高_Sql_Query Optimization_Sap Ase_Query Performance_Sql Execution Plan - Fatal编程技术网

SQL union优化为左连接,速度更快,但查询计划显示成本更高

SQL union优化为左连接,速度更快,但查询计划显示成本更高,sql,query-optimization,sap-ase,query-performance,sql-execution-plan,Sql,Query Optimization,Sap Ase,Query Performance,Sql Execution Plan,优化到 select id, c.name as name from a join b on a.id=b.id join c on a.id=c.id union select id, d.name as name from a join b on a.id=b.id join d on a.id=d.id 选择id, 如果c.name不为null或c.name“”则为c.name else d.name以name结尾 从a.id=b.id上的连接b a.id=c.id上的左连接c a.id

优化到

select id, c.name as name
from a join b on a.id=b.id
join c on a.id=c.id
union
select id, d.name as name
from a join b on a.id=b.id
join d on a.id=d.id
选择id,
如果c.name不为null或c.name“”则为c.name
else d.name以name结尾
从a.id=b.id上的连接b
a.id=c.id上的左连接c
a.id=d.id上的左连接d
其中c.name不为null或d.name不为null
查询响应时间从30秒提高到13秒

  • sql union=30秒
  • sql左连接=13秒
但是,在检查查询计划后,sql联合具有较低的I/O成本,请参见以下内容:

  • sql union=语句1(第1行)的总估计I/O成本:6277566
  • sql left join=语句1(第1行)的总估计I/O成本:10481124
我使用的是Sybase 12.5 ASE,查询计划来自DBArtisan 8.5;如果我需要上传整个查询计划,请告诉我。我对查询计划还不是很熟悉,但我在这里和那里做sql优化,通常我只是基于时间的改进。我还检查了两个查询的结果集是否相同(27949行)。我还屏蔽并简化了表名


我的问题是,这是否意味着sql左连接速度更快但资源更密集?如果是这样的话,我还应该选择更快的替代方案吗?

数据库将在内部进行一些缓存,因此执行时间并不总是最佳指标。如果您运行第一个查询,然后紧接着运行第二个查询,那么第二个查询就处于不公平的优势,因为一些数据可能会被缓存

与所有数据库调优问题一样,没有什么是一成不变的。我个人喜欢这个联盟,因为我认为它更具可读性,但严格地说,从性能角度来看,我会在更长的时间内进行一些扩展测试(以最小化缓存的影响),并查看它们的性能


这些表中有多少数据?这四个表中的id列有索引吗?如果没有,这将加快您的查询速度,更不用说对sql的任何更改。

查询计划通常基于统计数据,而实际查询执行将取决于实际数据。你的数据是最新的吗?什么是最新的?我刚刚执行了查询计划,我在这里发布的I/O号是最新的。数据库定期收集有关表的统计数据(记录数等),并使用这些统计数据确定查询计划。如果你的统计数据过时,那么这个计划可能不是最优的。例如,如果您创建一个新表并插入大量数据,并且未收集统计数据,则DB将执行查询,就像该表为空一样。这可能会导致一个糟糕的计划。
select id, 
       case when c.name is not null or c.name <> '' then c.name 
       else d.name end as name
from a join b on a.id=b.id
left join c on a.id=c.id
left join d on a.id=d.id
where c.name is not null or d.name is not null