6

Buduję bazę danych MySQL, która zawiera wpisy o specjalnych podciągach DNA w gatunkach drożdży. Moja tabela wygląda następująco:COUNT i GROUP BY na polach tekstowych wydaje się powolny

+--------------+---------+------+-----+---------+-------+ 
| Field  | Type | Null | Key | Default | Extra | 
+--------------+---------+------+-----+---------+-------+ 
| species  | text | YES | MUL | NULL |  | 
| region  | text | YES | MUL | NULL |  | 
| gene   | text | YES | MUL | NULL |  | 
| startPos  | int(11) | YES |  | NULL |  | 
| repeatLength | int(11) | YES |  | NULL |  | 
| coreLength | int(11) | YES |  | NULL |  | 
| sequence  | text | YES | MUL | NULL |  | 
+--------------+---------+------+-----+---------+-------+ 

Istnieje około 1,8 miliona rekordów. W jednym rodzaju zapytania Chcę zobaczyć ile DNA podciągi są związane z każdego rodzaju gatunków i regionu, więc wydaj zapytanie:

select species, region, count(*) group by species, region; 

gatunku i kolumny regionie tylko dwie możliwe pozycje (konserwowany/scer dla gatunków i promotora/kodowania regionu), ale to zapytanie zajmuje około 30 sekund.

Czy jest to normalny czas oczekiwania na tego typu zapytanie, biorąc pod uwagę rozmiar tabeli? Czy to jest powolne, ponieważ używam pól tekstowych zamiast prostych wartości całkowitych lub boolowskich (wolę pola tekstowe, ponieważ kilku badaczy spoza CS będzie używało DB). Wszelkie inne pomysły i sugestie byłyby mile widziane.

Proszę wybaczyć, jeśli jest to pytanie z głową kości, jestem neofitą SQL.

P.S. Widziałem także this question, ale proponowane rozwiązanie nie wydaje się odpowiednie dla tego, co robię.

EDYTOWANIE: Konwersja tych pól na VARCHARs zmniejszyła czas wykonywania do ~ 2,5 sekundy. Zauważ, że ja również wyliczyłem to w stosunku do ENUM, które miały podobny czas.

+0

Które pole jest twoim głównym kluczem? –

+0

Nie mam klucza podstawowego. Mógłbym sztucznie to zrobić, ale czy to miało znaczenie? – Rich

Odpowiedz

6

Dlaczego wszystkie kolumny oparte na ciągach są zdefiniowane jako TEKST? Jeśli przeczytasz porównanie wydajności, zobaczysz, że TEKST był ~ 3x wolniejszy niż kolumna VARCHAR z identycznym indeksowaniem: http://forums.mysql.com/read.php?24,105964,105964

+0

Dobry połów, nie zauważyłem, że były" tekstem " –

+0

Zrobiłem TEKST, ponieważ kolega kopalni powiedział, że nie będzie żadnej różnicy między tym i VARCHAR.) Korzystanie z VARCHAR wziął mój czas pracy z 33 sekund do 2.5. – Rich

+0

@Rich: Wow - nie spodziewałeś się tak dramatycznej różnicy. zmieniono kolumny gatunku i regionu na obce klucze na tabele z ich odpowiednimi wartościami, INT jest zawsze 4 bajty, natomiast VARCHAR (4) to 5, więc można sobie wyobrazić ile bajtów VARCHAR (100). –

3

Jeśli twoje pola będą miały tylko 2 wartości, znacznie lepiej będzie je polubić. Powinieneś także zrobić wszystko, co jest NOT NULL, chyba że istnieje prawdziwy powód, dla którego będziesz go potrzebować jako NULL.

Zobacz także ENUM type, aby uzyskać lepszy sposób użycia skończonej liczby wartości czytelnych dla człowieka w kolumnie.

Jeśli chodzi o powolność, pierwszą rzeczą, którą należy wypróbować, jest utworzenie indeksów na kolumnach. Dla danego zapytania jesteś pokazano tutaj, indeks na species, region powinny stanowić ogromną różnicę:

create index on mytablename (species, region); 

powinno wystarczyć.

+2

Czy jesteś pewien, że indeks sprawi ogromną różnicę w przypadku takich danych o niskiej liczności? –

+1

Nie, nie jestem tego pewien, ale myślę, że to dobra domysły. Zacząłem pisać o używaniu 'EXPLAIN', ale zaczęło przekształcać się w puszkę z robakami. I domyślam się, że ostatecznym rezultatem będzie prawdopodobnie to, że i tak powinniśmy spróbować stworzyć indeks. – Vineet

+0

Próbowałem indeks, ale to nie miało znaczenia. Próbowałem też VARCHAR jako OMG, który sugerował Kucyk, który był znacznie szybszy. Po tym spróbowałem go przed wyliczeniami bez zauważalnego przyspieszenia z VARCHAR-ów. – Rich