Domanda

Mi unisco a una tabella dozzine di volte diverse e ogni volta mi unisco (o filtro) in base ai risultati di una SUBSTRING di una delle colonne (è una stringa, ma con zeri riempiti a sinistra e non lo faccio) non mi interessano le ultime quattro cifre).Di conseguenza, anche se questa colonna è indicizzata e la mia query utilizzerebbe l'indice, esegue una scansione della tabella perché la SUBSTRING stessa non è indicizzata, quindi SQL Server deve calcolarla per ogni riga prima che si unisca.

Sto cercando qualche idea su come accelerare questo processo.Attualmente, c'è una vista sulla tabella (è un "SELECT * FROM", solo per dare alla tabella un nome descrittivo) e sto pensando di aggiungere una colonna alla vista calcolata e quindi di indicizzarla.Sono aperto ad altri suggerimenti, però: qualche idea?

PIÙ DETTAGLIO:Avrei dovuto condividerlo per cominciare.La tabella riceve la replica dal nostro sistema di fatturazione, pertanto la modifica della tabella sottostante per aggiungere una colonna calcolata non è un'opzione.Qualsiasi colonna calcolata dovrebbe essere aggiunta alla vista sulla tabella.Inoltre, gli zeri iniziali non sono sempre zeri iniziali: a volte sono altri dati a cui non sono interessato.Immagino che la vera domanda sia "Come posso unirmi ai dati nel mezzo di una colonna VARCHAR utilizzando anche un indice?Ricerca nel testo completo?"

Chiarire il mio esempioSto semplificando, ma in sostanza, diciamo che sto cercando di cercare valori in una colonna con i seguenti valori:

00000012345MoreStuff
00000012345Whatever
19834212345
Houses12345837443GGD
00000023456MoreStuff

Sono interessato alle righe in cui SUBSTRING(7,5)="12345", quindi vorrei le righe 1-4, ma non la riga 5.Quello che sto proponendo è aggiungere una colonna alla mia vista "SELECT *" che contiene questa sottostringa e quindi indicizzare in base a quella.Ha più senso?

È stato utile?

Soluzione

Supponendo di avere i campi in questo formato:

00Data0007
000000Data0011
0000Data0015

, è possibile effettuare le seguenti operazioni:

  • Crea una colonna calcolata: ndata AS RIGHT(REVERSE(data), LEN(data) - 4)

    Questo trasformerà le colonne nelle seguenti:

    ataD00
    ataD000000
    ataD0000
    
  • Crea un indice su quella colonna

  • Problema questa query per cercare la Data stringa:

    SELECT  *
    FROM    mytable
    WHERE   ndata LIKE N'ataD%'
            AND SUBSTRING(ndata, LEN(N'ataD') + 1, LEN(ndata)) = REPLICATE('0', LEN(ndata) - LEN('ataD'))
    

    La prima condizione userà un indice per filtrazione grossolana.

    Il secondo farà in modo che tutti i personaggi principali (che sono diventati i personaggi finali nella colonna calcolata) non sono altro che gli zeri.

Vedere questa voce nel mio blog per il dettaglio delle prestazioni:

Aggiorna

Se si desidera solo un indice su SUBSTRING senza cambiare lo schema, la creazione di una vista è un'opzione.

CREATE VIEW v_substring75
WITH SCHEMABINDING
AS
SELECT  s.id, s.data, SUBSTRING(data, 7, 5) AS substring75
FROM    mytable

CREATE UNIQUE CLUSTERED INDEX UX_substring75_substring_id ON (substring75, id)

SELECT  id, data
FROM    v_substring75
WHERE   substring75 = '12345'

Altri suggerimenti

Aggiungere un colonna calcolata alla tua tabella e crea un indice su questa colonna.

ALTER TABLE MyTable
Add Column CodeHead As LEFT(Code,Len(Code)-4)

Quindi crea un indice su questo.

CREATE INDEX CodeHeadIdx ON MyTable.CodeHead

Si può ri-frase i criteri di filtro in termini di una dichiarazione come 'qualcosa%'? (Questo è applicabile ad un indice)

Modificare la colonna a due colonne - i dati si uniscono in e il supplemento 4 caratteri. Utilizzando parti di una colonna rallenta le cose come si hve visto

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top