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())
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.
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.
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.
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.
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.
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.
143 ms totalt · 3 externa anrop · v20260731065814-full.b746b907