Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: przyspieszenie komendy SELECT
Forum PHP.pl > Forum > Bazy danych > MySQL
maston
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
WHERE id_osoby LIKE '5'
ałć.... winksmiley.jpg

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
Założyłes klucz na id_osoby?
Jeżeli nie to załóż. I pobieraj raczej te dane, ktore potrzebujesz
Mchl
Skąd masz MySQL 5.3.0?
maston
był indeks tylko na id wplaty. dodalem na id_osoby i juz jest ok. 2 sekundy pobiera smile.gif dzieki wielkie.
P.S. nie 5.3.0 tylko 5.1.36 pomylilem z PHP smile.gif
nospor
Cytat
2 sekundy pobiera
nadal dlugo. wywaliles tego LIKE jak ci pisalem?
Mchl
Tak myślałem ;P

Pokaż co EXPLAIN pokazuje dla tego zapytania
http://dev.mysql.com/doc/refman/5.0/en/explain.html
maston
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

  1. FIELD Type NULL KEY DEFAULT Extra
  2. id_wplaty int(11) NO PRI NULL AUTO_INCREMENT
  3. id_przydzialu int(50) NO MUL NULL
  4. id_osoby varchar(50) YES MUL NULL
  5. id_kursu varchar(50) YES MUL NULL
  6. dane_odbiorcy text YES NULL
  7. brutto varchar(30) NO NULL
  8. opis varchar(255) YES NULL
  9. vat varchar(30) YES NULL
  10. netto varchar(30) YES NULL
  11. towar varchar(100) YES NULL
  12. id_towaru varchar(50) YES NULL
  13. termin varchar(50) NO NULL
  14. data_wystawienia varchar(30) YES NULL
  15. data_sprzedazy varchar(30) YES NULL
  16. numer_fv varchar(150) YES NULL
  17. osoba varchar(150) YES NULL
  18. user_add_time varchar(150) YES NULL
  19. oddzial varchar(50) YES NULL
  20. extra_info text YES NULL
  21. pkwiu varchar(50) YES NULL
  22. platnosc varchar(3) YES NULL
  23. korekta_nr varchar(255) YES NULL
  24. korekta_kwota varchar(255) YES NULL
  25. korekta_osoba varchar(255) YES NULL
  26. korekta_data varchar(255) YES NULL
  27. korekta_user_add varchar(255) YES NULL
  28. okres varchar(50) NO NULL
  29. kasa varchar(10) YES NULL
nospor
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 smile.gif
Mchl
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
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
Poza tym wydaje się, że ta tabela zasługuje na normalizację.
wujekleon
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.
Invision Power Board © 2001-2025 Invision Power Services, Inc.