Optimización de consultas - ¿Por qué esta velocidad hasta la consulta?
-
20-09-2019 - |
Pregunta
Estoy usando SAPO de Quest para SQL Server 2000 en un servidor SQL Server.
Aquí está mi consulta:
SELECT CASE SLCE.GroupName WHEN 'Other' THEN ARM.FBCOMPANY
WHEN 'Inter Co.' THEN ARM.FBCOMPANY
ELSE SLCE.GroupName END AS [Company Name],
ARM.fcustno AS [Cust No],
ARM.fbcompany AS [Cust Name],
ARM.fcinvoice AS [Invoice No],
ARM.fdgldate AS [Post Date],
year(arm.fdgldate) AS [Year Posted],
CASE ARM.fcsource WHEN 'S' THEN 'Shipper'
WHEN 'O' THEN 'Sales Order'
WHEN 'R' THEN 'Receiver'
WHEN 'C' THEN 'Customer'
ELSE ARM.fcsource END AS [Source Doc Type],
CASE ARM.fcstatus WHEN 'N' THEN 'New'
WHEN 'U' THEN 'Unpaid'
WHEN 'P' THEN 'Partially Paid'
WHEN 'F' THEN 'Paid in Full'
WHEN 'H' THEN 'Held'
WHEN 'V' THEN 'Voided'
ELSE ARM.fcstatus END AS [Invoice Status],
ARM.fpono AS [Cust PO No],
ARM.fsalespn AS [Sales Person],
ARI.fitem AS [Item No],
ARI.fprodcl AS [Prod Class],
ARI.fshipkey AS [Qty Invoiced],
ARI.ftotprice AS [Net Invoiced],
ARI.fpartno AS [Part No],
ARI.frev AS [Part Rev],
cast(ARI.fmdescript AS VARCHAR(20)) AS [Part Description],
ARM.fsono AS [Sales No],
ARI.fsokey AS [SO Rels Key],
ARI.fordqty AS [Qty Ordered],
RED.[YEAR] AS [Year],
RED.PERIOD AS [RF Period]
FROM dbo.armast ARM
INNER JOIN dbo.aritem ARI
ON ARM.FCINVOICE = ARI.FCINVOICE
INNER JOIN slcdpm SLC
ON SLC.fcustno = ARM.fcustno
LEFT OUTER JOIN slcdpm_ext SLCE
ON SLC.identity_column = SLCE.fkey_id
INNER JOIN REDFRIDAYDATES..TBLREDFRIDAYALLDATES RED
ON RED.date = CAST (FLOOR (CAST (ARM.fdgldate AS FLOAT)) AS DATETIME)
WHERE ARM.fcstatus <> 'V'
AND RED.[YEAR] = year(getdate())
AND ari.frev = 'REP'
AND ARI.fsalesacc IN ('4010001', '4010002', '4010003', '4010004', '4010005', '4010006', '4010007', '4010008', '4010009', '4010010', '4010018', '4010019', '4010020', '4010021', '4010031', '4010050', '4022000', '4031000', '4045000', '4055000', '4057000', '4060000', '4070000')
Aquí está la opción de SAPO (con diferencias de relieve) es:
INNER JOIN dbo.aritem ARI
ON ARM.FCINVOICE = ***COALESCE (ARI.FCINVOICE , ARI.FCINVOICE)***
INNER JOIN slcdpm SLC
ON SLC.fcustno = ARM.fcustno
LEFT OUTER JOIN slcdpm_ext SLCE
ON SLC.identity_column = SLCE.fkey_id
INNER JOIN REDFRIDAYDATES..TBLREDFRIDAYALLDATES RED
ON RED.date = CAST (FLOOR (CAST (ARM.fdgldate AS FLOAT)) AS DATETIME)
WHERE ARM.fcstatus <> 'V'
AND RED.[YEAR] = year(getdate())
AND ari.frev = 'REP'
AND ARI.fsalesacc IN ('4010001', '4010002', '4010003', '4010004', '4010005', '4010006', '4010007', '4010008', '4010009', '4010010', '4010018', '4010019', '4010020', '4010021', '4010031', '4010050', '4022000', '4031000', '4045000', '4055000', '4057000', '4060000', '4070000')
***AND ARI.[fpartno] >= CHAR(0)***
Por favor alguien puede decirme por que se unen y adicionales y la declaración de acelerar esta consulta en más de un 50%?
Solución
¿Ha echado un vistazo a los planes de ejecución reales. Esto debería mostrar los diferentes enfoques que se llevó a SQL Server en la ejecución de estas consultas.
Otros consejos
Es, definitivamente, una extraña. El plan de ejecución se debe decir con seguridad, pero los cambios de rendimiento de este tipo en las bases de datos casi siempre descendido a un índice. Así que mi mejor conjetura es que el servidor SQL de alguna manera le faltaba un índice que podría utilizar y la adición de estos cambios impares hizo que destaque mejor.
Sin embargo, si usted está mirando para aprender el 'por qué' involucrados para que la próxima vez que usted puede escribir su consulta para ser más rápido en el primer lugar, no hay nada allí.
A WAG completa:
Voy a suponer que fpartno tiene una condición de "no nulo" en él (por lo que el filtro añadido pasa siempre), y que sapo pasa saber que SQL Server no es lo suficientemente inteligente como para detectar que> = CHAR (0) es siempre cierto. Así que esto sugiere que sapo está tratando de guiar, de una manera muy oblicua, el optimizador de utilizar algo que ha fpartno en ella. Algo que podría ser un índice compuesto de (fcinvoice, fpartno) .. ¿tienes uno de esos?
Al igual que los otros dijeron, explicar el plan debería resultar útil para explicar el misterio.
Ninguno de estos cambios tienen ningún efecto en el significado lógico de la consulta (es decir, son "no hay ops")
El único efecto físico que el COALESCE en la cláusula ON sería la de impedir que el optimizador de tratar de usar un índice para ARI.FCINVOICE.
Del mismo modo, el único efecto físico que el "> = CHAR (0)" podría tener sobre el optimizador de podría sea para empujar a considerar el uso de un rango de exploración indexada (o también buscan) en un índice que tenía ARI. [fpartno] en ella.
Así que mi conclusión sería que SAPO está tratando de manipular el optimizador en el uso de un índice en particular sin tener que forzando a utilizar ese índice con una sugerencia explícita. En realidad, eso es un poco inteligente como el verdadero problema con las sugerencias del optimizador de T-SQL es sus dependencias y fragilidad.