none
Indices de columnas varchar RRS feed

  • Pregunta

  • Estimados.

    En un SS2012 tengo algunos indices con columnas varchar, el problema es que son varchar(8000), como podria consultar todos los indices que contengan columnas como las indicadas ?


    DBA SQL Server Santiago/Chile

    martes, 29 de agosto de 2017 22:04

Respuestas

  • Efectivamente, tienes razón. Para obtener los nombres de los índices que no coinciden con claves, hay que usar las vistas de sistema sys.*, ya que el Information_Schema no te los da.

    Por desgracia las tabas sys.* son una pesadez, porque no traen los nombres sino IDs y luego hay que resolver los nombres. Al final sale un JOIN de un montón de tablas. Tienes un ejemplo en la respuesta a esta pregunta de StackOverflow:

    https://stackoverflow.com/questions/765867/list-of-all-index-index-columns-in-sql-server-db

    SELECT 
         TableName = t.name,
         IndexName = ind.name,
         IndexId = ind.index_id,
         ColumnId = ic.index_column_id,
         ColumnName = col.name,
         ind.*,
         ic.*,
         col.* 
    FROM 
         sys.indexes ind 
    INNER JOIN 
         sys.index_columns ic ON  ind.object_id = ic.object_id and ind.index_id = ic.index_id 
    INNER JOIN 
         sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id 
    INNER JOIN 
         sys.tables t ON ind.object_id = t.object_id 
    WHERE 
         ind.is_primary_key = 0 
         AND ind.is_unique = 0 
         AND ind.is_unique_constraint = 0 
         AND t.is_ms_shipped = 0 
    ORDER BY 
         t.name, ind.name, ind.index_id, ic.index_column_id;

    • Propuesto como respuesta Moderador M viernes, 1 de septiembre de 2017 19:08
    • Marcado como respuesta Moderador M lunes, 4 de septiembre de 2017 21:46
    jueves, 31 de agosto de 2017 6:38

Todas las respuestas

  • Haz un select sobre INFORMATION_SCHEMA.KEY_COLUMN_USAGE. Verás que te devuelve la tabla, el esquema y el nombre del índice y el nombre de la columna que está indexada. Con el nombre de la tabla, el esquema y la columna puedes hacer un select sobre INFORMATION_SCHEMA.COLUMNS para sacar la longitud de la columna.

    Una observación: Creo que se puede producir un problema al tener un índice sobre una columna que sea un varchar(8000), y es que los índices tienen un límite de longitud de 900 caracteres. Así que si en algún momento se introduce en esa columna un valor con más de 900 caracteres, el índice probablemente no funcionará como se espera. No lo he probado, no sé si dará un error o simplemente despreciará los caracteres que le sobren.

    • Propuesto como respuesta Moderador M miércoles, 30 de agosto de 2017 16:20
    miércoles, 30 de agosto de 2017 6:35
  • Muchas gracias Alberto, lo mirare ahora mismo.

    Con respecto al indice de un varchar(8000) esta totalmente mal pues la longitud maxima de lso datos es de 50 :)


    DBA SQL Server Santiago/Chile

    miércoles, 30 de agosto de 2017 14:21
  • Estimado Alberto.

    Al consultar INFORMATION_SCHEMA.KEY_COLUMN_USAGE me deuelve los nombres de las claves pero NO de los indices.


    DBA SQL Server Santiago/Chile

    miércoles, 30 de agosto de 2017 20:20
  • Efectivamente, tienes razón. Para obtener los nombres de los índices que no coinciden con claves, hay que usar las vistas de sistema sys.*, ya que el Information_Schema no te los da.

    Por desgracia las tabas sys.* son una pesadez, porque no traen los nombres sino IDs y luego hay que resolver los nombres. Al final sale un JOIN de un montón de tablas. Tienes un ejemplo en la respuesta a esta pregunta de StackOverflow:

    https://stackoverflow.com/questions/765867/list-of-all-index-index-columns-in-sql-server-db

    SELECT 
         TableName = t.name,
         IndexName = ind.name,
         IndexId = ind.index_id,
         ColumnId = ic.index_column_id,
         ColumnName = col.name,
         ind.*,
         ic.*,
         col.* 
    FROM 
         sys.indexes ind 
    INNER JOIN 
         sys.index_columns ic ON  ind.object_id = ic.object_id and ind.index_id = ic.index_id 
    INNER JOIN 
         sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id 
    INNER JOIN 
         sys.tables t ON ind.object_id = t.object_id 
    WHERE 
         ind.is_primary_key = 0 
         AND ind.is_unique = 0 
         AND ind.is_unique_constraint = 0 
         AND t.is_ms_shipped = 0 
    ORDER BY 
         t.name, ind.name, ind.index_id, ic.index_column_id;

    • Propuesto como respuesta Moderador M viernes, 1 de septiembre de 2017 19:08
    • Marcado como respuesta Moderador M lunes, 4 de septiembre de 2017 21:46
    jueves, 31 de agosto de 2017 6:38