maston
27.04.2010, 11:47:11
Witam.
Mam w tabeli ponad 120 000 rekordów. 4 kolumny wykorzystywane w skrypcie. Wykonanie jednego zapytania SELECT * FROM wplaty WHERE id_osoby LIKE '5' trwa okolo 9 sekund. Zwracane jest 10 rekordów, bo tyle do tej osoby należy.
Czy da się w jakiś sposób zmniejszyć liczbę sekund, żeby generowanie 10 wierszy nie zajmowało tyle czasu?
Typ tabeli MyISAM, wersja MySQL 5.3.0, sprzęt klasy średniej: 768 MB ramu, procek 1,4 GHz, Windows XP Proffesional.
Dzięki z góry
Pozdrawiam
nospor
27.04.2010, 11:49:25
WHERE id_osoby LIKE '5'
ałć....

WHERE id_osoby = 5
Poczytaj w manualu co do czego sluzy i do tego uzywaj
ps: zakladam tez ze masz index na id_osoby zalozony?
wookieb
27.04.2010, 11:49:36
Założyłes klucz na id_osoby?
Jeżeli nie to załóż. I pobieraj raczej te dane, ktore potrzebujesz
Mchl
27.04.2010, 11:55:53
Skąd masz MySQL 5.3.0?
maston
27.04.2010, 12:05:19
był indeks tylko na id wplaty. dodalem na id_osoby i juz jest ok. 2 sekundy pobiera

dzieki wielkie.
P.S. nie 5.3.0 tylko 5.1.36 pomylilem z PHP
nospor
27.04.2010, 12:06:57
Cytat
2 sekundy pobiera
nadal dlugo. wywaliles tego LIKE jak ci pisalem?
Mchl
27.04.2010, 12:09:04
Tak myślałem ;P
Pokaż co EXPLAIN pokazuje dla tego zapytania
http://dev.mysql.com/doc/refman/5.0/en/explain.html
maston
27.04.2010, 12:23:48
pozmienialem w kodzie LIKE na = i ograniczylem typy danych do potrzebnych dlugosci. bo wszedzie bylo varchar(255) i jest 0,9 sekundy.
a explain pokazuje
FIELD Type NULL KEY DEFAULT Extra
id_wplaty int(11) NO PRI NULL AUTO_INCREMENT
id_przydzialu int(50) NO MUL NULL
id_osoby varchar(50) YES MUL NULL
id_kursu varchar(50) YES MUL NULL
dane_odbiorcy text YES NULL
brutto varchar(30) NO NULL
opis varchar(255) YES NULL
vat varchar(30) YES NULL
netto varchar(30) YES NULL
towar varchar(100) YES NULL
id_towaru varchar(50) YES NULL
termin varchar(50) NO NULL
data_wystawienia varchar(30) YES NULL
data_sprzedazy varchar(30) YES NULL
numer_fv varchar(150) YES NULL
osoba varchar(150) YES NULL
user_add_time varchar(150) YES NULL
oddzial varchar(50) YES NULL
extra_info text YES NULL
pkwiu varchar(50) YES NULL
platnosc varchar(3) YES NULL
korekta_nr varchar(255) YES NULL
korekta_kwota varchar(255) YES NULL
korekta_osoba varchar(255) YES NULL
korekta_data varchar(255) YES NULL
korekta_user_add varchar(255) YES NULL
okres varchar(50) NO NULL
kasa varchar(10) YES NULL
nospor
27.04.2010, 12:25:24
Cytat
i ograniczylem typy danych do potrzebnych dlugosci. bo wszedzie bylo varchar(255)
id_osoby varchar(50)
zrobienie z id_osoby varchar to tez nie najlepszy pomysl. Tu chyba powinien byc INT. Zakladam ze idosoby to liczba a nie tekst
Mchl
27.04.2010, 12:28:32
Chciałem EXPLAIN SELECTa, a nie tabeli... No ale z tego też widać, że jeszcze struktura tabeli pozostawia do życzenia.
Kod
Field Type Null Key Default Extra
id_wplaty int(11) NO PRI NULL auto_increment
id_przydzialu int(11) NO MUL NULL
id_osoby int(11) YES MUL NULL
id_kursu varchar(50) YES MUL NULL
dane_odbiorcy text YES NULL
brutto decimal(8,2) NO NULL
opis varchar(255) YES NULL
vat deciaml(8,2) YES NULL
netto decimal(8,2) YES NULL
towar varchar(100) YES NULL
id_towaru int(11) YES NULL
termin date NO NULL
data_wystawienia date YES NULL
data_sprzedazy date YES NULL
numer_fv varchar(150) YES NULL
osoba varchar(150) YES NULL
user_add_time datetime YES NULL
oddzial varchar(50) YES NULL
extra_info text YES NULL
pkwiu char(11) YES NULL
platnosc varchar(3) YES NULL
korekta_nr varchar(255) YES NULL
korekta_kwota varchar(255) YES NULL
korekta_osoba varchar(255) YES NULL
korekta_data varchar(255) YES NULL
korekta_user_add varchar(255) YES NULL
okres varchar(50) NO NULL
kasa varchar(10) YES NULL
Kilka sugestii zmian
thek
27.04.2010, 14:43:27
Chcesz kolejne sugestie? Nie używaj w kolumnie NULL. Ustawiaj NOT NULL, gdyż to rozwiązanie szybsze. tam gdzie tylko liczby masz używaj INT. Jeśli dane są w jakiś sposób możliwe do podziału - zastosuj kilka tabel mniejszych, oddzielając w szczególności te, które mają częsty zapis/edycję. Pola, po których łączysz te tabelę z innymi ustaw jako indeks. To samo z tymi, których używasz w WHERE czy ORDER BY. Staraj unikać konstrukcji SELECT * jeśli nie pobierasz wszystkich danych z tabeli. Ogólnie rzecz biorąc pooglądaj nieco dział optymalizacji w dokumentacji choćby MySQL bo wiele tam ciekawych wskazówek.
Mchl
27.04.2010, 14:52:48
Poza tym wydaje się, że ta tabela zasługuje na normalizację.
wujekleon
1.05.2010, 17:57:33
Conajmniej 3 różne tabele powinny być
np.
faktura
pozycje_na_fakturze
korekty
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę
kliknij tutaj.