0

我有一个 SQL Server 查询,它在 SQL Server Management Studio 或 TADOQuery 上以毫秒为单位运行,但在 TFDQuery 上运行需要 17 秒。

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

if OBJECT_ID('tempdb..#DADES') is not null DROP TABLE #DADES

SELECT 'O' tipus,l.numero as Comanda, o.NumeroOrdre as Ordre, ag.nom as Client,
       c.Referencia, o.estat, max(a.Descripcio) descripcio, ag.provincia, c.ProvinciaEnvio,c.poblacioEnvio,c.codiPostalEnvio,c.adresaEnvio,c.telefonoEnvio,
       c.Transportista, o.ObservacionsTransport, o.DataCarrega, o.DataEntrega,
       case when tipusOrdre=1 then 'PANEL' else case when tipusOrdre=2 then 'TAPAJUNT' else 'ALTRES' end end Tipus2,
       dbo.f_palets_pendents(o.NumeroOrdre) as paletsPendents ,
       dbo.f_palets_assignats(o.NumeroOrdre) as paletsAssignats,
       c.ports,
       sum(dbo.f_pes_linia_comanda(l.numero,L.linia)) pes_lin,
       c.envio
INTO #DADES
FROM OrdresFabricacio o
     LEFT OUTER JOIN LiniesComandesVendes l ON o.NumeroOrdre=l.numeroordre
     LEFT OUTER JOIN CapsaleraComandesVendes c ON c.Numero=l.numero
     LEFT OUTER JOIN CapsaleraAgenda ag ON ag.codi=c.client
     LEFT OUTER JOIN Articles a ON a.codi=l.article
WHERE o.Transport=63163
GROUP BY l.numero,o.NumeroOrdre,ag.nom,c.Referencia, o.estat,ag.provincia,c.ProvinciaEnvio,c.poblacioEnvio,c.codiPostalEnvio,c.adresaEnvio,c.telefonoEnvio,
         c.Transportista, o.ObservacionsTransport, o.DataCarrega, o.DataEntrega,o.tipusOrdre,c.ports,c.envio
OPTION(RECOMPILE)

默认情况下,我使用所有选项在新的 TFDConnection 和 TFDQuery 上运行它们。SET TRANSACTION ISOLATION LEVEL READ COMMITTED我确保它在与 SQL Server Management Studio 相同的隔离级别上运行。我into #DADES强制不返回任何数据(而是将其复制到临时表中),因此我可以丢弃任何潜在的问题并延迟将数据提取到本地缓冲区。最后,WITH(RECOMPILE)我强制 SQL Server 重新评估查询的执行计划(以防止使用一些带有过时统计信息的旧计划)。

此外,我还尝试禁用 TFDConnection 的 ResourceOptions 上的所有命令文本处理选项,但没有任何改进。

问题似乎与dbo.f_pes_linia_comanda()函数有关,因为用表达式替换它会使相同的查询在毫秒内正确运行。就像是 :

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

if OBJECT_ID('tempdb..#DADES') is not null DROP TABLE #DADES

SELECT 'O' tipus,l.numero as Comanda, o.NumeroOrdre as Ordre, ag.nom as Client,
       c.Referencia, o.estat, max(a.Descripcio) descripcio, ag.provincia, c.ProvinciaEnvio,c.poblacioEnvio,c.codiPostalEnvio,c.adresaEnvio,c.telefonoEnvio,
       c.Transportista, o.ObservacionsTransport, o.DataCarrega, o.DataEntrega,
       case when tipusOrdre=1 then 'PANEL' else case when tipusOrdre=2 then 'TAPAJUNT' else 'ALTRES' end end Tipus2,
       dbo.f_palets_pendents(o.NumeroOrdre) as paletsPendents ,
       dbo.f_palets_assignats(o.NumeroOrdre) as paletsAssignats,
       c.ports,
       sum(l.Quantitat) pes_lin,
       c.envio
INTO #DADES
FROM OrdresFabricacio o
FROM OrdresFabricacio o
     LEFT OUTER JOIN LiniesComandesVendes l ON o.NumeroOrdre=l.numeroordre
     LEFT OUTER JOIN CapsaleraComandesVendes c ON c.Numero=l.numero
     LEFT OUTER JOIN CapsaleraAgenda ag ON ag.codi=c.client
     LEFT OUTER JOIN Articles a ON a.codi=l.article
WHERE o.Transport=63163
GROUP BY l.numero,o.NumeroOrdre,ag.nom,c.Referencia, o.estat,ag.provincia,c.ProvinciaEnvio,c.poblacioEnvio,c.codiPostalEnvio,c.adresaEnvio,c.telefonoEnvio,
         c.Transportista, o.ObservacionsTransport, o.DataCarrega, o.DataEntrega,o.tipusOrdre,c.ports,c.envio
OPTION(RECOMPILE)

所以我的问题是,是否有人知道为什么 FireDAC 在具有一些标量函数时运行查询速度较慢?为什么他们使用不同的执行计划而不是直接向 SQL Server Management Studio 上的引擎发送完全相同的查询?一种获取用于 TFDQuery 的执行计划的方法,这样我就可以看到它出了什么问题并尝试解决它?

谢谢你。

4

0 回答 0