Pregunta

Yo estaba trabajando con una consulta que me escribió hoy tenía que cambiar el código de la WHERE cláusula de utilizar una(lista de cosas) filtro en lugar de usar algo como

item_desc = 'item 1'
OR item_desc = 'item 2'
OR item_desc = 'item 3'
OR item_desc = 'item 4'

El de arriba se ejecutó durante 15 minutos y se devuelve nada, pero la siguiente me dio mi conjunto de resultados en 1,5 minutos

item_desc IN (
'item 1'
,'item 2'
,'item 3'
,'item 4'
)

Hice esto en SQL y me pregunto por qué la(lista de elementos) se realiza de forma mucho más rápida luego de la declaración.

-- EDIT -- SQL Server 2008, pido disculpas por no poner esta info en el primer lugar.

Esta es la Consulta en su totalidad mediante la OR declaraciones:

DECLARE @SD DATETIME
DECLARE @ED DATETIME
SET @SD = '2013-06-01';
SET @ED = '2013-06-15';

-- COLUMN SELECTION
SELECT PV.PtNo_Num AS 'VISIT ID'
, PV.Med_Rec_No AS 'MRN'
, PV.vst_start_dtime AS 'ADMIT'
, PV.vst_end_dtime AS 'DISC'
, PV.Days_Stay AS 'LOS'
, PV.pt_type AS 'PT TYPE'
, PV.hosp_svc AS 'HOSP SVC'
, SO.ord_no AS 'ORDER NUMBER'
--, SO.ent_dtime AS 'ORDER ENTRY TIME'
--, DATEDIFF(HOUR,PV.vst_start_dtime,SO.ent_dtime) AS 'ADM TO ENTRY HOURS'
, SO.svc_desc AS 'ORDER DESCRIPTION'
, OSM.ord_sts AS 'ORDER STATUS'
, SOS.prcs_dtime AS 'ORDER STATUS TIME'
, DATEDIFF(DAY,PV.vst_start_dtime,SOS.prcs_dtime) AS 'ADM TO ORD STS IN DAYS'

-- DB(S) USED
FROM smsdss.BMH_PLM_PtAcct_V PV
JOIN smsmir.sr_ord SO
ON PV.PtNo_Num = SO.episode_no
JOIN smsmir.sr_ord_sts_hist SOS
ON SO.ord_no = SOS.ord_no
JOIN smsmir.ord_sts_modf_mstr OSM
ON SOS.hist_sts = OSM.ord_sts_modf_cd

-- FILTER(S)
WHERE PV.Adm_Date BETWEEN @SD AND @ED
AND SO.svc_cd = 'PCO_REMFOLEY'
OR SO.svc_cd = 'PCO_INSRTFOLEY'
OR SO.svc_cd = 'PCO_INSTFOLEY'
OR SO.svc_cd = 'PCO_URIMETER'

AND SO.ord_no NOT IN (
    SELECT SO.ord_no
    FRROM smsdss.BMH_PLM_PtAcct_V PV
    JOIN smsmir.sr_ord SO
    ON PV.PtNo_Num = SO.episode_no
    JOIN smsmir.sr_ord_sts_hist SOS
    ON SO.ord_no = SOS.ord_no
    JOIN smsmir.ord_sts_modf_mstr OSM
    ON SOS.hist_sts = OSM.ord_sts_modf_cd
    WHERE OSM.ord_sts = 'DISCONTINUE'
    AND SO.svc_cd = 'PCO_REMFOLEY'
    OR SO.svc_cd = 'PCO_INSRTFOLEY'
    OR SO.svc_cd = 'PCO_INSTFOLEY'
    OR SO.svc_cd = 'PCO_URIMETER'
)
ORDER BY PV.PtNo_Num, SO.ord_no, SOS.prcs_dtime

Gracias,

¿Fue útil?

Solución

Oleski la respuesta es incorrecta.Para SQL Server 2008, un IN lista consigue rediseñados para una serie de OR las declaraciones.Puede ser diferente en decir MySQL.

Estoy bastante seguro de que, si se ha generado reales de ejecución de los planes tanto de las consultas serían idénticos.

Con toda probabilidad la segunda consulta corría más rápido porque se corrió la segunda, y la primera consulta ya habían arrancado todas las páginas de datos de la base de datos y del pago de la IO costo.La segunda consulta fue capaz de leer todos los datos de la memoria y ejecutar mucho más rápido.

Actualización

La fuente real de la varianza es probable que las consultas son no equivalente.Se tienen dos diferentes OR lista de abajo:

WHERE PV.Adm_Date BETWEEN @SD AND @ED
AND SO.svc_cd = 'PCO_REMFOLEY'
OR SO.svc_cd = 'PCO_INSRTFOLEY'
OR SO.svc_cd = 'PCO_INSTFOLEY'
OR SO.svc_cd = 'PCO_URIMETER'

y más tarde

 WHERE OSM.ord_sts = 'DISCONTINUE'
    AND SO.svc_cd = 'PCO_REMFOLEY'
    OR SO.svc_cd = 'PCO_INSRTFOLEY'
    OR SO.svc_cd = 'PCO_INSTFOLEY'
    OR SO.svc_cd = 'PCO_URIMETER'

En tanto los WHERE cláusulas, operador precendence (donde Y es manejado antes O) significa que la propia lógica ejecutado por el motor es:

WHERE (ConditionA AND ConditionB)
OR ConditionC
OR ConditionD
OR ConditionE

Si va a reemplazar el OR listas con un IN la expresión, la lógica será:

WHERE ConditionA
AND (ConditionB OR ConditionC OR ConditionD OR ConditionE)

Que es radicalmente diferente.

Otros consejos

La mejor manera de saberlo es mirar el plan de consulta real con algo similar EXPLAIN.Esto debe decirle a usted exactamente lo que el DBMS está haciendo, y entonces usted puede obtener una mejor idea de por qué es más eficiente.

Con eso dicho, DBMS sistemas son realmente buenos para hacer operaciones entre dos tablas (como se une).Un montón de que el optimizador del tiempo que se gasta en estas partes de las consultas, ya que generalmente son más caros.

Por ejemplo, el DBMS puede ordenar que IN lista y, mediante un índice de item_desc, filtrar los resultados muy rápidamente.Usted no puede hacer que la optimización cuando se lista un montón de selecciones como en el primer ejemplo.

Cuando se utiliza IN, usted está haciendo una improvisada mesa y filtrado mediante estos más eficiente de la tabla de combinación de técnicas.

EDITAR:He publicado esta respuesta antes de OP menciona el DBMS específico.Este es el resulta NO ser la forma en que SQL Server trata esta consulta, pero puede ser válido para otros sistemas DBMS.Ver JNK la respuesta para obtener información más específica, precisa respuesta.

Licenciado bajo: CC-BY-SA con atribución
scroll top