2015-07-22 17 views
6

Będzie bardzo dobrze - pełne, jeśli ktoś dostarczy mi niewielką pomoc w mysql.Przecięcie Mysql dwóch zestawów o wartości oddzielonej przecinkiem

Posiadam tabelę zawierającą 1 miliard rekordów, w których jedna kolumna ma wartość oddzielenia przecinkami.

Mam wartości rozdzielone przecinkami do wyszukiwania.

Chcę wybrać te wiersze, które mają dowolną wartość w kolumnie oddzielone przecinkami od tej wartości ciągu.

przykład, tabela jest o kolumna comma_separated w następujący sposób: -

enter image description here

i mają łańcuch o oddzielony przecinkami wartości "79, 62, 70, 107".

Wynik będzie numer wiersza 1,2,3,5,7,8,9,10 (W wzmianka obrazu.)

Zrobiłem to z regex, ale to zajmuje zbyt dużo czasu, więc chcę tego uniknąć w celu optymalizacji.

+0

Proszę pokazać nam swoje próby. –

+0

To bardzo zły projekt bazy danych! – Jens

+0

Inne rozwiązanie myślę, więc zrób to z funkcją zapisaną (która użyje pętli z funkcją find_in_set), która zapewni wartość boolean do ustawienia i użycia w zapytaniu. Ale nie wiem jak to zrobić. –

Odpowiedz

2

Nie można naprawdę zoptymalizować tego, co robisz. Zasadniczo można uruchomić kwerendę w następujący sposób:

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 

Wymaga to pełnego skanowania tabeli. I chociaż wydajność może być nieco lepsza niż zwykłe wyrażenie, nadal nie będzie wydajna.

Właściwym sposobem przechowywania tych danych jest ich łączenie. Powoduje to zwielokrotnienie liczby wierszy, więc pierwszy wiersz danych staje się trzema rzędami w tabeli skrzyżowań (po jednym dla każdej wartości).

Istnieje wiele powodów, dla których nie chcesz przechowywać list rzeczy jako listy rozdzielanej przecinkami. Twoje wartości wyglądają jak id w innej tabeli, co jeszcze bardziej pogarsza:

  • Wartości powinny być przechowywane w ich macierzystym formacie. Zatem przechowywanie liczb całkowitych jako łańcuchów jest złym pomysłem.
  • Natywną strukturą dla list w SQL jest tabela, a nie lista.
  • Funkcje tabel są bardziej wydajne i mają funkcje ciągów.
  • SQL nie może używać indeksów (z wyjątkiem pełnotekstowych indeksów) do operacji na łańcuchach.
  • Gdy masz identyfikator odwołujący się do innej tabeli, powinieneś mieć ograniczenie klucza obcego. Nie można tego zrobić z listami zapisanymi w ciągu znaków.
0

Jeśli chodzi o wydajność, należy rozważyć modyfikację struktury bazy danych. Liczby nie indeksują się dobrze (jeśli w ogóle) w tekstowych typach kolumn.

Wygląda na to, że masz stałą liczbę liczb całkowitych w kolumnie "przecinek".

Należy rozważyć utworzenie oddzielnej kolumny typu INT dla każdej z trzech, tj.:

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

Następnie można zrobić właściwego doboru jak:

WHERE 
    num1 IN (79, 62, 70, 107) 
    OR num2 IN (79, 62, 70, 107) 
    OR num3 IN (79, 62, 70, 107) 
Powiązane problemy