Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][SQL] wydajność wyszukiwania w bazie po nazwie
Forum PHP.pl > Forum > PHP
phpuser88
Zastanawiam się czy przy kilkunastu tysiącach rekordów w SQL (MariaDB) będzie duży problem jeżeli będę wyszukiwał rekordy za pomocą nazwy(VARCHAR) zamiast id(INT)?
Chodzi o wczytywanie zawartości z kilku tabel za pomocą wartości textowej z linku $_GET . Kiedyś, kilka lat temu gdzieś wyczytałem że generuje to dużo większe obciążenie i nie warto, a mi zależy na ładnych linkach bez cyfr i zastanawiam się jak podejść do problemu...

Miał ktoś może już z tym doświadczenie? Myślę nad takim rozwiązaniem:
1. Utworzyć nową tabele `link` z VARCHAR (nazwa linku) i INT (id linku), a następnie po wprowadzeniu linku w adres przeglądarki zapytać tabele `link` i dopiero później zapytać właściwe tabele z treścią po ID - ale czy to będzie szybsze niż szukanie bezpośrednie po nazwie w tabeli pierworodnej? tym bardziej, że link będzie się składać z dwóch wartości textowych...

Jeszcze nad tym nie pracuje, ale czeka mnie to w najbliższych dniach i myślę jak to ugryżć najlepiej wydajnościowo. Może jest na to konkretne rozwiązanie? z góry dzięki za komentarze.
aras785
Prawdopodobnie chcesz szukać po tzw. slug - odpowiadając: dodaj index dla kolumny slug/link i nie zauważysz żadnej różnicy.
phpuser88
Dzięki za odpowiedź. Czyli wychodzi na to, że jednak wyjściem będzie utworzenie dodatkowej tabeli z wartością tekstową i ID linku, a następnie przy otrzymaniu linku np. /nazwa-listy będzie trzeba odpytać SQL, aby uzyskać ID_listy i następnie za pomocą ID_listy odpytać kilka pozostałych tabel w celu wczytania wszystkich danych na podstrone... hmm... sadsmiley02.gif
aras785
Nie wiem jak masz to rozwiązane ale jeśli chcesz pobierać zawartość jakiegoś wpisu w bazie po VARCHAR zaniast INT (np. ID) to dodaj kolumne: link lub slug i po prostu zamiast WHERE id = :id, zrób WHERE slug = :slug lub WHERE link = :link (https://mansfeld.pl/programowanie/kurs-pdo-bazy-danych-php/)
phpuser88
Hm.. może posłużmy się jakimś przykładem:
Link: local/podstrona.php?load=nazwa
Zostanie przerobiony za pomoca htaccess na: local/podstrona/nazwa

Teraz za pomocą $_GET['load'] bede musial wczytac dane z kilku tabel (A,B,C,D) i tu pojawia się pytanie czy w kazdej tabeli utworzyc kolumne `link` (link==nazwa) i za pomoca `link` wczytywac odpowiednie dane, czy moze lepiej utworzyc jedna dodatkową tabele (X) gdzie najpierw znajde globalne `ID` dla podstrony za pomoca `link==nazwa` i pozniej za pomoca `ID` zapytac o dane tabele (A,B,C,D)?

z tyłu głowy ciągle myślę o wydajności znajdywania tekstu w SQL zamiast liczb.

Troche łapatologiczny opis, ale lepszy taki niz wcale^^ dzięki!
viking
Zapewne daleko ci jeszcze do problemu wydajności. Jakbyś miał kilkanaście milionów rekordów to wtedy możesz się martwić.
phpuser88
Myślę przyszłościowo, ale jak widać zbyt poważnie podchodzę do tematu wydajności przez wyszukiwanie za pomocą nazwy zamiast id. Dzięki.
trueblue
Jak rozumiem link czy jego fragment szukasz w kilku tabelach - dlaczego tak się dzieje?
phpuser88
@trueblue, chcę wczytać zawartość podstrony za pomocą wartości $_GET z linku, ale chce też posiadać linki bez numerków i stąd zapytanie jak to najlepiej rozwiązać.
trueblue
Ale moje pytanie dotyczyło czego innego.
Dlaczego na podstawie $_GET['load'] przeszukujesz kilka tablic?
phpuser88
Bo śmigam na starym strukturalnym PHP 5.6 i jest to bardzo wygodne i bezpieczne rozwiązanie po uprzednim filtrze zawartości $_GET mellow.gif
trueblue
Chyba się nie dogadamy.
Co ma wersja PHP do bazy danych?

Cały czas pytam dlaczego przeszukujesz tablice A, B, C, D, a nie jedną tablicę, pod kątem wartości zmiennej $_GET['load']?
phpuser88
Przy wczytywaniu danych z SQL sposób i wersja PHP ma znaczenie z tego co zauważyłem po obecnie panujących standardach obiektowych.
Tablica A to podstawowe dane. B+C to różne dane dodatkowe, a D to zdarzenia w formie jeśli $_GET['X'] istnieje w `D` to wyświetl X.

Tylko że... nie operuje na gotowym przykładzie, to wszystko jest jedynie wizją niedalekiej przyszłości nad którą zastanawiam się w formie odskoczni od tworzenia kompletnego front-end'a.
Teraz pomyślałem, że rozwiąże wyczytywanie danych z kilku tabel w inny sposób. Mianowicie utworze dodatkową tablice cache, napisze osobny skrypt, który odpyta wszystkie tablice za pomocą crona co określony czas (lub lepiej, co określony update/insert) i skumuluje wszystkie niezbędne dane w tablicy cache, żeby później zaoszczędzić na wydajności przeszukiwania kilku tablic jednocześnie X razy.
Kolejnym krokiem zaoszczędzenia na wydajności wydaje się być generowanie w całości, wraz z wszystkimi danymi najpopularniejszych stron - mam dobry tok myślenia czy przesadzam i tablica z cache wystarczy?
Ostatnio programowałem w PHP coś "większego" z 10 lat temu i teraz moja wiedza jest jedynie historią...
aras785
Szukasz rozwiązania dla problemu który nie istnieje i póki co zostaw wydajność w spokoju.
Sprawdź sobie jak buduje się relacje między tabelami... szybki przykład poniżej: https://www.db-fiddle.com/f/eEw6tAEd6UTPQDbQhqc2ot/1

Operuję tylko na pages, resztę sobie wczytuję niezależnie od LINKU/SLUG.
trueblue
Proponowałbym jednak założyć indeks (zwykły lub unikalny) na polu ze slug'iem.
phpuser88
Tak zrobię, zostawię wydajność w spokoju.
Przykład jest świetny jako przedstawienie problemu i przypomnienie podstaw SQL.
Nałożę też indexa na sluga.

Dzięki wielkie za wsparcie i nakierowanie na prawidłowy tok myślenia.
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-2024 Invision Power Services, Inc.