prplxrMedlem sedan juni 2012582 inlägg Hej!
Har ett skript där man kan mata in ett helt eller en del av ett sökord för att få förslag på liknande sökord för att man sedan enkelt ska kunna välja och importera dessa som sina egna. Hmm, lurigt att förklara.
Frågan ser ut såhär:
$sql = "SELECT DISTINCT Sokord AS so FROM tblSokord WHERE Sokord LIKE '%" . $word . "%' UNION SELECT DISTINCT DoldSokord AS so FROM tblSokord WHERE DoldSokord LIKE '%" . $word . "%' LIMIT 0, 10"
Tabellen har drygt 46 000 rader och ytterligare en tabell ska tillföras på ytterligare runt 20 000 rader och detta håller inte måttet. Kan jag optimera den där frågan på något sätt? Behöver hjälp med detta!
Det skulle kunna vara så att LIMIT 0,10 anses tillhöra andra frågan, dvs inte "hela uttrycket" som du kanske förväntar dig. Om det är så bör du lägga till en limit på det första uttrycket också:
$sql = "SELECT DISTINCT Sokord AS so FROM tblSokord WHERE Sokord LIKE '%" . $word . "%' LIMIT 0, 10 UNION SELECT DISTINCT DoldSokord AS so FROM tblSokord WHERE DoldSokord LIKE '%" . $word . "%' LIMIT 0, 10"
Du kan ju också kolla hur många rader uttrycket returnerar oförändrat. (med mysql_num_rows())
prplxrMedlem sedan juni 2012582 inlägg Precis vad jag också funderade på när jag postat frågan. Ska testa det!
Btw, jag använder mig av MySQL 5.5.24.
När jag funderar på saken, båda sökningarna sker ju io samma tabell. Varför behöver du en UNION?
$sql = "SELECT DISTINCT COALESCE(Sokord, DoldSokord) AS so FROM tblSokord WHERE Sokord LIKE '%" . $word . "%' OR DoldSokord LIKE '%" . $word . "%' LIMIT 0, 10"
COALESCE, om du undrar, returnerar det första av de värden som ges till det som inte är NULL. Exempelvis, om en rad matchar DoldSokord och Sokord är null för den raden, returneras DoldSokord.
prplxrMedlem sedan juni 2012582 inlägg Tack för tipset! Jag hade faktiskt ingen aning om att det ens fanns någon sådant funktionalitet! :o
Men ett varningens ord. Det där kräver ju att ett tomt fält representeras som just NULL och inte en tom sträng. Då kommer du ju få ett tomt resultat för de rader där DoldSokord matchar och Sokord är en tom sträng.
prplxrMedlem sedan juni 2012582 inlägg Okej, det är jag med på. Intressant nog har jag ej "Allow NULL" på fälten, ändå får jag inga tomma resultat. Dock har jag inget default value på fälten heller.
Men det kan ju bero på att din sökning bara returnerar rader där det är Sokord som matchas. Prova
$sql = "SELECT DISTINCT COALESCE(Sokord, DoldSokord) AS so FROM tblSokord WHERE DoldSokord LIKE '%" . $word . "%' LIMIT 0, 10"
och se om du får några tomma rader.
Hur är datastrukturen utformad? Vad ska Sokord innehålla om DolSokord innehåller något? (Och tvärtom)
Problemet är din LIKE-sats, den är extremt långsam. Den går inte att optimera, dessvärre. Det du behöver är någon form av fulltextindexering, just nu får den gå igenom rad för rad, tecken för tecken, när den söker.
aasahMedlem sedan mars 20034 471 inlägg En annan sak att se upp med är att aldrig använda IN, UNION (eller andra mängdoperationer) mot ett värde/resultat som kan innehålla NULL. När en sådan fråga faktiskt innehåller NULL tar den en eeeeeeeeevvvviiiiiiiiiiiiiiiiiiiiiiiiiigggghhhhhheeeeeeeeeeeeeettttt. För att undvika det kan man tex se till att NULL-värden istället jämförs under något annat värde.
aasah: Jag tror du jämför äpplen och päron. Mönstret WHERE x IN (SELECT y FROM …) är ökänt för att göra frågos snorlångsamma eftersom varje post måste jämföras mot en lista. Däremot finns det ingen större anledning varför UNION skulle bli mycket långsammare om resultaten innehåller NULL. UNION ska ju bara foga samman två listor och på sin höjd kolla att resultaten är unika om man inte kör UNION ALL.
aasahMedlem sedan mars 20034 471 inlägg
nitro2k01 skrev:
aasah: Jag tror du jämför äpplen och päron. Mönstret WHERE x IN (SELECT y FROM …) är ökänt för att göra frågos snorlångsamma eftersom varje post måste jämföras mot en lista. Däremot finns det ingen större anledning varför UNION skulle bli mycket långsammare om resultaten innehåller NULL. UNION ska ju bara foga samman två listor och på sin höjd kolla att resultaten är unika om man inte kör UNION ALL.
Jag är ganska säker på att i alla fall SQL Server har (haft) ett känt problem med mängdjämförelser och NULL-värden. Infon är dock ett par år gammal, så det kanske inte längre är relevant.