2015-07-22 12 views
6

Sarà molto completo se qualcuno mi fornirà un piccolo aiuto in mysql.Intersezione Mysql di due set con valore separato da virgola

Ho una tabella con 1 miliardo di record in cui una colonna con valore separato da virgole.

Ho un valore separato da virgola da cercare.

Desidero selezionare quelle righe che hanno valore di chiunque in quella colonna separata da virgola da quel valore di stringa.

per esempio, tabella è una vista colonna comma_separated simili: -

enter image description here

e ho una stringa avente valori separati da virgola "79, 62, 70, 107".

Risultato sarà numero di riga 1,2,3,5,7,8,9,10 (In menzione immagine.)

ho fatto con regex, ma sta prendendo troppo tempo, quindi voglio evitare questo per scopo di ottimizzazione.

+0

Vi preghiamo di mostrare ai vostri tentativi. –

+0

È una pessima progettazione del database! – Jens

+0

Un'altra soluzione a cui sto pensando, lo fa con la funzione memorizzata (che utilizzerà il ciclo con la funzione find_in_set) che fornirà booleano per l'impostazione e l'uso nella query. Ma non so come farlo. –

risposta

2

Non si può davvero ottimizzare ciò che si sta facendo. Fondamentalmente, è possibile eseguire una query come questa:

where find_in_set(79, comma_separated) > 0 or 
     find_in_set(62, comma_separated) > 0 or 
     find_in_set(70, comma_separated) > 0 or 
     find_in_set(107, comma_separated) > 0 

Ciò richiede una scansione di tabella completa. E, anche se le prestazioni potrebbero essere leggermente migliori di un'espressione regolare, non saranno comunque efficienti.

Il modo corretto per archiviare questi dati è come una tabella di congiunzione. Questo moltiplica il numero di righe, quindi la prima riga dei dati diventa tre righe nella tabella di giunzione (una per ogni valore).

Esistono numerosi motivi per cui non si desidera memorizzare elenchi di elementi come elenchi separati da virgole. I tuoi valori appaiono come identificativi in ​​un'altra tabella, peggiorando le cose:

  • I valori devono essere memorizzati nel loro formato nativo. Quindi, memorizzare gli interi come stringhe è una cattiva idea.
  • La struttura nativa per gli elenchi in SQL è una tabella, non una lista.
  • Le funzioni sulle tabelle sono più potenti e le funzioni di stringa.
  • SQL non può utilizzare gli indici (ad eccezione degli indici di testo completo) per le operazioni con le stringhe.
  • Quando si ha un ID che si riferisce a un'altra tabella, si dovrebbe avere un vincolo di chiave esterna. Non è possibile farlo con elenchi memorizzati in una stringa.
0

Se si è interessati alle prestazioni, è consigliabile modificare la struttura del DB. I numeri non sono indicizzati correttamente (se non del tutto) in tipi di colonne basati su testo.

Sembra che tu abbia un numero costante di numeri interi nella colonna "virgola_separata".

Prendere in considerazione la creazione di una colonna di tipo INT separata per ciascuno dei tre, vale a dire.:

num1 | num2 | num3 
79 | 62 | 101 
101 | 5 | 70 

allora si potrebbe fare una scelta corretta del tipo:

WHERE 
    num1 IN (79, 62, 70, 107) 
    OR num2 IN (79, 62, 70, 107) 
    OR num3 IN (79, 62, 70, 107) 
Problemi correlati