Jag visar en massa data i en lista (tabell) på en hemsida.
Listan kan bland annat sorteras med hjälp av AJAX. På så sätt behöver inte hela sidan laddas om då listan sorteras. Snabbt och snyggt är tanken.
Mitt "problem" är bara det att datan som visas i listan måste hämtas på nytt från databasen varje gång listan sorteras. Det känns inte riktigt rätt. Vad som skulle vara bättre är ifall datan bara hämtas en enda gång och sedan lagra den i en variabel som i sin tur manipuleras varje gång en sortering utförs. Förslagsvis i en session.
Frågeställning:
Är det ett bra sätt, eller hur skulle Du göra? Jag känner en viss oro för prestandan när jag lagrar säg 3000 användare med en massa info kring i en session (som i sin tur lagras på min server). Är den oron befogad?
En annan grej som har med detta att göra. Listan visar 30 rader åt gången och man kan hoppa framåt och bakåt (så som det brukar se ut i vanliga listor/tabeller). Detta sköts också med hjälp av AJAX. Även här hämtas all data på nytt varje gång man "hoppar framåt och bakåt" i listan.
Frågeställning:
All data hämtas (inte bara 30 rader) från databasen. Detta för att jag ska veta hur listan egentligen är och kunna skriva ut "< bakåt | sida 1, sida 2, sida 3 | framåt >". Hur ska jag göra istället? Är det rent prestandamässigt bättre att bara ta reda på antalet rader i databasen och sedan i en separat query hämta 30 rader?
Exempel:
// Hämta antalet
$sql = "
SELECT COUNT(userID) AS antal
FROM users
";
// Hämta 30 användare
$sql = "
SELECT *
FROM users
LIMIT 30
";
Finns det bättre sätt att ta reda på antalet rader? Ett annat problem som jag ser det är att om inte alla rader hämtas så blir det svårt att sortera dem korrekt. Då måste ju själva sorteringen utföras i queryn mot databasen... Och då spricker ju hela konceptet!
Det skulle vara intressant att veta hur andra gör med sina listor, för nästintill alla hemsidor innehåller ju någon form av listor (grids)!
Tack för att Du tagit dig tid att läsa mitt långa inlägg, och hoppas du kan hjälpa mig. :bire
Jag kan inte AJAX, så om det finns smarta AJAX-varianter kan jag inte svara på.
Men så länge du ändå hämtar ny data från databasen varje gång har jag svårt (möjligen felaktigt) att se nyttan med att hämta alla 3000 raderna var gång du behöver 30 st. Det låter inte som om du vinner något mot att hämta de rader du behöver direkt från databasen.
Själv använder jag följande Kjellkod ;) (Skrivet av Kjell som startade wF.) OBS! att två rader måste anpassas så de går ihop med dina tabeller.
(Strängt taget använder jag idag en något omarbetad version som lagt all pagingkod i en funktion, vilket underlättar omsortering på olika kolumner, så väl som återanvändning på olika sidor, men jag har inte tillgång till den just nu eftersom jag inte är hemma.)
Jag skulle definitivt anropa databasen på nytt varje gång användaren byter sida. Du måste ju ändå anropa databasen på nytt om användaren ändrar sorteringen för att få ett nytt resultset, alternativt sortera med php och det är knappast snabbare i stora listor. Bättre att lägga det jobbet på databasen tycker jag, den är ju gjord för sånt.
Du har ju information om sidan de befinner sig på, antal poster per sida och aktuell sortering. Med den infon kan du skapa en sql-fråga som hämtar de 1-30 posterna som ska visas. Du ska aldrig behöva hämta alla poster från databasen någon gång. Det är mycket bättre prestandamässigt att köra med en limit. Nästan alla pagineringsystem jag sett delar upp det i två frågor som du gjort i ditt exempel. Det tar bara några millisekunder att köra count frågan ändå så det skulle jag inte ora mig för.
Men eftersom du använder ajax kan du ju låta pagineringen vara statisk, dvs du skapar den bara varje gång sidan laddas in. Det är ju bara själva listan du vill ladda om så storleken på sökresultatet kan du spara undan nånstans så blir det bara en fråga ändå.
Jag skulle också överväga om sortering "live" är nödvändigt. De flesta sidor tillåter bara sortering innan man söker och vill man ha en annan sortering får man söka igen. Det brukar ju fungera bra för det mesta även om det inte är lika flashigt som ajax :)
...
Du kanske känner till det redan men ett bra sätt att hämta posterna på är nått sånt här:
$page = 3; //aktuell sida
$limit = 30; //max antal poster per sida
$start = ceil( ($page - 1) * $limit);
$sort = "title DESC" //aktuell sortering
SELECT * FROM articles ORDER BY $sort LIMIT $start, $limit
Synpunkter?
Läs igen vad jag skrev ovan. Spara värdet från din count query efter sökningen så kan du använda det för pagineringen. Då behövs bara en fråga för att hämta posterna varje gång användaren byter sida. Det går snabbare att hämta och gå igenom max 30 poster än alla dina poster varje gång ja :)
Det blir svårt att sortera listan på det vis som pulse rekommenderar, dvs direkt i sql-queryn, i stället för att sortera den sammansatta arrayen.
Varför?
Jo, om jag hämtar data om användaren från flera olika tabeller i olika querys, t.ex. användardata, loggbok, bilar, hus osv. Datan ska ju visas i samma lista.
Hajar ni problemet?
Om jag t.ex. sorterar efter loggboken (när användaren senast loggade in) så blir ju ordningen fel i de andra... Svårt att förklara på ett enkelt sätt.
Huuur kan man lösa detta? Det känns som att jag i slutänden måste hämta all data varje gång ändå... Trist!
Jag tror jag ska testa köra på sessioner ändå. Så länge det inte är väldigt prestandakrävande tycker jag det är en mycket bra idé. Då blir det endast en db-query där all data hämtas. Sedan när ajax körs så hämtas datan ur sessionen. Smidigt.
Så, då undrar jag bara över det här med prestandan.
1. Hur mycket kan man lagra i en session?
2. Finns det några rekommendationer?
3. Hur mycket utrymme tar en array uppbyggd enligt följande:
// Datan
$data[] = array("username"=>"alex", "email"=>"alex@olsson.se");
$data[] = array("username"=>"kalle", "email"=>"kalle@kent.se");
$data[] = array("username"=>"olle", "email"=>"olle@abb.se");
// Spara tabellerna som arrayer i en session
$_SESSION["tables"]["test"] = array("headlines"=>"Användarnamn, E-post","data"=>$data);
$_SESSION["tables"] är alltså en tredimensionell(?) array som kan innehålla flera olika tabeller med rubriker och data/rader ($data). $data kommer kunna innehålla flera tusen rader (användare).
4. Kan man räkna ut storleken i bytes på en array enligt ovan? Finns verktyg för detta kanske?
Förstår inte riktigt hur din sökning är uppbyggd men det låter som du vill visa mycket data och då kan det ju vara svårt att få in allting i en fråga. Har du försökt JOIN:a ihop allting med Sql? Går det inte så är väl sessioner ett bra alternativ antar jag.
Sessioner lagras inte i minnet utan i en katalog på servern som en vanlig fil så du behöver inte oroa dig för att det inte får plats.
memory_get_usage mäter hur mycket minne ditt script förbrukar under en körning och har inget med sessionerna att göra. Däremot kan det ju vara viktigt att hålla koll på ändå.
Om jag t.ex. sorterar efter loggboken (när användaren senast loggade in) så blir ju ordningen fel i de andra... Svårt att förklara på ett enkelt sätt.
Du vet väl att du kan sortera på mer än en kolumn i en SQL-fråga?
Det är ju bara att du bestämmer dig för vad du vill sortera efter och rangordnar det. Tex först på datum något postats i loggboken, senast överst,
sedan anvnamn, A först, sedan bilmärke Ö först:
ORDER BY loggdate DESC, name ASC, carBrand DESC
Till exempel...
(Förutsatt att allt hämtas i en fråga, men annars uppstår väl knappast sorteringsproblemet...?)
Du vet väl att du kan sortera på mer än en kolumn i en SQL-fråga?
Det är ju bara att du bestämmer dig för vad du vill sortera efter och rangordnar det. Tex först på datum något postats i loggboken, senast överst,
sedan anvnamn, A först, sedan bilmärke Ö först:
ORDER BY loggdate DESC, name ASC, carBrand DESC
Till exempel...
(Förutsatt att allt hämtas i en fråga, men annars uppstår väl knappast sorteringsproblemet...?)
Tack för tipset. Allt kördes inte i samma fråga förut men nu har jag slagit ihop allt. Lite pilligt med joins hit och dit till en början men nu tycks det fungera...! Jag tror inte längre på sessions-modellen som jag tidigare förespråkat, den känns lite "ful"...