2012-06-13 18 views
25

Actualmente estoy haciendo algunas pruebas para determinar las implicaciones de rendimiento de incluir un índice en una columna determinada en SQL Server 2005.¿Cómo puedo forzar una consulta para que no use un índice en una tabla determinada?

El conjunto de datos de prueba que estoy usando tiene aproximadamente ~ 72 millones de filas (aproximadamente 6 GB de datos). Para realmente probar el rendimiento del índice, necesito poder comparar el rendimiento con y sin el índice allí.

Eso está muy bien, pero crear un índice en primer lugar no es una operación barata. Si quiero probar la tabla sin el índice, necesito, como mínimo, deshabilitar el índice. Para probar con el índice, necesito volver a habilitarlo, lo que lleva bastante tiempo.

¿Hay alguna forma en que pueda forzar a SQL Server 2005 a ignorar un índice dado cuando está ejecutando una consulta? No quiero tener que deshabilitar el índice solo para probar una consulta, ya que demora tanto tiempo para deshabilitar el índice.

+1

[También podría consultar 'DBCC AUTOPILOT'] (http://blogs.solidq.com/fabianosqlserver/post.aspx?id=39&title=undocumented,%22statistics_only%22,%20%22dbcc%20autopilot%22 % 20and% 20% 22set% 20autopilot% 22) –

Respuesta

37
SELECT * 
FROM MyTable WITH (INDEX(0)) 
WHERE MyIndexedColumn = 0 

de consulta normalmente utilizar el índice en MyIndexedColumn, pero debido a la sugerencia de tabla, lo hará en su lugar tablescan.


SELECT * 
FROM MyTable WITH (INDEX(IndexName)) 
WHERE MyIndexedColumn = 0 

de consulta normalmente utilizar el índice en MyIndexedColumn, pero debido a la sugerencia de tabla, en su lugar utilizará el índice llamado IndexName.

+0

Así que si tengo en 'MyTable' los índices' PK_MyTable' y 'IX_MyTable_MyIndexedColumn', puedo usar' WITH (INDEX (PK_MyTable)) 'para forzarlo * not * a usar el índice en 'MyIndexedColumn'? –

+1

Sí. Examine el ExecutionPlan para confirmar este comportamiento. http: // stackoverflow.com/questions/7359702/how-do-i-obtain-a-query-execution-plan –

+0

¿Qué sucede con los casos en que otros índices no agrupados se presentan? ¿Cómo hacer que el servidor sql se base en el índice y no en el índice recién creado, para comprobar cómo el nuevo índice ayuda a la consulta? – Satyajit

-2

Puede deshabilitar el índice que no desea usar en la misma transacción en la que está ejecutando el código de prueba, solo asegúrese de deshacer la transacción al final. Esto garantiza que el código de prueba no usará el índice pero evita que el índice realmente se desactive.

BEGIN TRANSACTION 

    ALTER INDEX [MyIndex] ON MyTable DISABLE; 

    EXEC TestCode; 

ROLLBACK 

Esto funciona mejor si usted tiene un caso complejo en el que el código de prueba utiliza una serie de índices en diferentes momentos y desea probar si la adición de una nueva mejoraría las cosas.

+4

¡Su consulta está bloqueando el esquema completo de la base de datos hasta que se ejecuten todos los lotes en la transacción! –

+0

No voté pero tengo que estar de acuerdo con Milán. No solo eso, sino que muchas veces tengo que probar algo como esto en una base de datos de producción y no hay manera de que los DBA me den permiso para alterar un índice en producción. –

5

Estoy trabajando con todos los tipos diferentes de DB y nunca recuerdo la pista específica cuando la necesito. Por lo tanto, estoy usando un enfoque de SQL puro que (actualmente) funciona con todos los DB que se cruzan en mi camino.

La idea es simplemente hacer que sea imposible para el DB utilizar el índice específico ofuscando la expresión respectiva en el SQL. P.ej.

SELECT * 
    FROM MyTable 
WHERE MyIndexedColumn + 0 = 0 

De forma similar, puede agregar una cadena vacía a un valor de cadena. Los optimizadores actuales no resuelven que tales expresiones no pueden usar un índice en (MyIndexedColumn).

Esto es realmente un antipatrón que describí en mi libro. Aquí hay algunos en la página acerca de math in SQL

Definitivamente es lo suficientemente bueno para pruebas ad-hoc. En el código de producción, ¡las pistas son más expresivas, por supuesto!

+1

Eso es terriblemente inteligente, pero parece aprovechar una deficiencia en lugar de una característica documentada, y probablemente no sea la mejor opción, dependiendo de la necesidad. – Paul

Cuestiones relacionadas