Pregunta

Estoy usando Sybase 12.5.3 (ASE) ; Soy nuevo en Sybase pesar de que he trabajado con MSSQL bastante ampliamente. Estoy corriendo en un escenario en el que un procedimiento almacenado es realmente muy lento. He rastreado el problema a un solo prop SELECT para una tabla relativamente grande. La modificación de esa declaración mejora drásticamente el rendimiento del procedimiento (y revertir drásticamente ralentiza; es decir, el prop SELECT es sin duda el culpable).

-- Sybase optimizes and uses multi-column index... fast!<br>
SELECT ID,status,dateTime
FROM myTable
WHERE status in ('NEW','SENT')
ORDER BY ID

-- Sybase does not use index and does very slow table scan<br>
SELECT ID,status,dateTime
FROM myTable
WHERE status in (select status from allowableStatusValues)
ORDER BY ID

El código anterior es una versión adaptada / simplificada del código real. Tenga en cuenta que ya he intentado volver a compilar el procedimiento, la actualización de las estadísticas, etc.

No tengo ni idea de por qué Sybase ASE elegiría un índice sólo cuando las cadenas están codificadas y elija un recorrido de tabla en la elección de otra tabla. Alguien por favor, dame una pista, y gracias de antemano.

¿Fue útil?

Solución

tema 1.El aquí es pobre codificación. En su comunicado, la mala código y pobre diseño de la tabla son las principales razones (98%) del optimizador toma decisiones incorrectas (los dos van mano a mano, no he descubierto la que la proporción de cada uno). Ambos:

    WHERE status IN ('NEW','SENT')

y

    WHERE status IN (SELECT status FROM allowableStatusValues)

son deficientes, ya que en ambos casos la causa ASE para crear una mesa de trabajo de los contenidos entre los soportes, que pueden evitarse fácilmente (y todos los problemas consecuentes evitado con él). No hay posibilidad de estadísticas sobre una mesa de trabajo, ya que las estadísticas de ambos t.status o s.status faltan (AdamH es correcta volver a ese punto), se elige correctamente un recorrido de tabla.

Las subconsultas tienen su lugar, pero nunca como un sustituto de un puro (las tablas son Relacionado) unirse. Las correcciones son:

    WHERE status = "NEW" OR status = "SENT"

y

    FROM  myTable t,
          allowableStatusValues s
    WHERE t.status = s.status

comunicado 2.

|. Ahora usted no tiene que añadir un índice para obtener estadísticas sobre una columna, pero que es probablemente la mejor manera

es incorrecta. Nunca crear índices que no se va a utilizar. Si quieres estadísticas actualizadas en una columna, simplemente

    UPDATE STATISTICS myTable (status)

3.It es importante asegurarse de que usted tiene las estadísticas actuales sobre (a) todas las columnas indizadas y (b) todos se unen columnas.

4.Yes, no hay sustituto para SHOWPLAN en cada segmento de código que se destina para la liberación, doblemente para cualquier código con el desempeño cuestionable. Puede también SET NOEXEC ON, para evitar la ejecución, por ejemplo. para grandes conjuntos de resultados.

Otros consejos

Una sugerencia de índice funcionará a su alrededor, pero probablemente no es la solución.

En primer lugar me gustaría saber si hay un índice en allowableStatusValues.status, si no es entonces Sybase tienen estadísticas sobre el mismo y tendrá una buena idea sobre el número de valores en ese país. Si no, entonces el optimizador probablemente no va a tener una buena idea de cuántas diferentes valores de estado puede tomar. Es entonces tener que hacer la suposición de que usted va a ser la extracción de casi todas las filas de myTable, y la mejor forma de hacer esto es un recorrido de tabla (si no hay índice de cobertura).

Ahora usted no tiene que añadir un índice para obtener estadísticas sobre una columna, pero es probablemente la mejor manera.

Si usted tiene un índice en allowableStatusValues.status, entonces me pregunto lo bien que sus estadísticas son. Usted obtener una copia de sp__optdiag . Es probable que también hay que ajustar los valores de "factor de histograma de sintonía" y "número de pasos de histograma", aumentando éstas ligeramente de los valores por defecto le dará estadísticas más detalladas que siempre ayuda al optimizador.

¿Todavía hacer un recorrido de tabla si se reemplaza la subconsulta con una combinación:

SELECT m.ID,m.status,m.dateTime 
FROM myTable m
JOIN allowableStatusValues a on m.status = a.status
ORDER BY ID 

En lugar de confiar en las observaciones experimentales de cuánto tiempo tarda una consulta para funcionar, lo recomiendo encarecidamente para conseguir Sybase para lograr que los planes de ejecución para cada consulta, por ejemplo:

SET showplan ON
GO

-- query/procedure call goes here
SELECT id, status, datetime
FROM myTable
WHERE status IN('NEW','SENT')
ORDER BY id
GO

SET showplan OFF
GO

Con SET showplan ON, Sybase genera planes de ejecución para cada instrucción se ejecuta. Estos pueden ser muy valiosa para ayudar a identificar donde las consultas no están haciendo uso de los índices adecuados. Para los procedimientos almacenados en Sybase, se genera el plan de ejecución de todo el procedimiento cuando el procedimiento almacenado se ejecuta primero después de haber sido compilada.

En caso de publicar los planes para cada una de las consultas que podría ser capaz de arrojar más luz sobre el problema.

Sorprendentemente, el uso de un índice de pistas resuelve el problema (ver el (myIndexName índice) debajo de la línea - re-escrito / Código simplififed a continuación:

-- using INDEX HINT
SELECT ID,status,dateTime 
FROM myTable (index myIndexName)
WHERE status in (select status from allowableStatusValues) 
ORDER BY ID 

extraño que Tienes para utilizar esta técnica para evitar un recorrido de tabla, pero no ir ya.

Garrett, mostrando sólo el código simplificado, se han despojado propensos a cabo exactamente la información que iluminaría la fuente del problema.

Mi primera conjetura sería una falta de correspondencia entre el tipo allowableStatusValues.status y myTable.status. Sin embargo, esa no es la única posibilidad. Como ninesided se ha dicho, los planes de consulta completos (con plan de presentación y banderas FMTONLY), así como las definiciones de las tablas reales y la fuente procedimiento almacenado, es mucho más probable que produzca una respuesta útil.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top