Avatar billede jakl2 Nybegynder
25. marts 2010 - 11:14 Der er 5 kommentarer og
1 løsning

Kompleks søgening

Hej Eksperter

Vores produkt søgning blev simpelthen for tung og langsom.

Derfor er jeg begyndt at skrive den forfra.

Mit problem er nu denne linje:
products_collection as pc ON p.collection_id = pc.id

Feltet
collection_id er et varchar
pc.id er et int

På en eller anden måde bliver collection_id lavet om til int så den finder nogle forkerte data frem, som ikke hører til dette produkt.

Det smarteste var hvis jeg på en eller anden måde kun lavede denne left join hvis collection_id kun indholdte tal. Er det muligt?

SELECT
    p.products_id,
    pd.products_name,
    pd.products_description_1,
    pd.products_description_2,
    pd.products_description_3,
    pc.products_id AS pc_products_id,
    pc.products_name AS pc_products_name,
    pc.products_description
   
FROM
    products AS p
   
    JOIN
        products_description AS pd ON p.products_id = pd.products_id
   
    LEFT JOIN
        products_collection as pc ON p.collection_id = pc.id
       
    LEFT JOIN
        specification_values as sv ON p.products_id = sv.products_id
   
WHERE
        p.products_status = 1
    AND
        pd.language_id = 4
       
   
       
       
       
       
       
    AND (
            p.products_id LIKE '%".$keyword."%'
        OR
            pd.products_name LIKE '%".$keyword."%'
        OR
            pd.products_description_1 LIKE '%".$keyword."%'
        OR
            pd.products_description_2 LIKE '%".$keyword."%'
        OR
            pd.products_description_3 LIKE '%".$keyword."%'
        OR
            pc.products_id LIKE '%".$keyword."%'
        OR
            pc.products_name LIKE '%".$keyword."%'
        OR
            pc.products_description LIKE '%".$keyword."%'
        OR
            sv.value LIKE '%".$keyword."%'
    )
       
GROUP BY
    p.collection_id
Avatar billede intenz Novice
25. marts 2010 - 13:13 #1
Jeg ville nu mene, at det smarteste ville være at du ikke blandede varchar og int sammen i et kolonne. Men at ændre kan kan selvfølgelig være en større omgang, afhængig af din kode.

Der er en diskussion om det samme, med nogle eksempler på hvordan det kan løses her:
http://forums.mysql.com/read.php?60,1907,1907#msg-1907
Avatar billede intenz Novice
25. marts 2010 - 13:19 #2
Grunden til den er langsom er nok også pga det her:

AND (
            p.products_id LIKE '%".$keyword."%'
        OR
            pd.products_name LIKE '%".$keyword."%'
        OR
            pd.products_description_1 LIKE '%".$keyword."%'
        OR
            pd.products_description_2 LIKE '%".$keyword."%'
        OR
            pd.products_description_3 LIKE '%".$keyword."%'
        OR
            pc.products_id LIKE '%".$keyword."%'
        OR
            pc.products_name LIKE '%".$keyword."%'
        OR
            pc.products_description LIKE '%".$keyword."%'
        OR
            sv.value LIKE '%".$keyword."%'
    )

Bare køre sådan en LIKE '%word%' en gang kan gøre ondt hvis du har en stor tabel. At køre den 9 gange på forskellige tabeller/kolonner kan gøre rigtig ondt.
Avatar billede jakl2 Nybegynder
25. marts 2010 - 13:54 #3
intenz >

Det giver mig faktisk to løsninger:
products_collection as pc ON p.collection_id = CONCAT('', 0 + pc.id)

eller

products_collection as pc ON p.collection_id = CAST(pc.id AS CHAR)

Hvilken vil så være mest korrekt?
Der er desværre ikke mulighed for at ændre så det er to int felter.

Angående LIKE, så er der vel ikke andre muligheder når det drejer sig om søgning?
Avatar billede intenz Novice
25. marts 2010 - 14:56 #4
Jeg har ikke selv haft behov for at gøre det du vil, så jeg kan ikke sige hvilken er mest korrekt at bruge. Hvis du ikke oplever mærkebar forskel på performance, og de begge giver et korrekt resultat, tror jeg ikke det betyder det store.
Hvis du har lyst, kan du måle performance og så bare tage den hurtigste.

Der findes masser af den slags scripts på google, her er et tilfældigt udvalgt:
http://www.ebrueggeman.com/article_php_execution_time.php
(om det virker, ved jeg ikke. Men mon ikke det gør).

Ang. LIKE, så finder der en del muligheder, nogle mere komplekse end andre.
Du kan implementere en 'lookup table', som indeholder alle ordene og peger på det produkt de tilhører. Det kræver dog sandsynligvis (afhængig af dit system) en del ændringer for at få til at virke. Så det er måske ikke den bedste løsning.

Du kan også bruge mysql's full-text søgning/indeksering. Det vil være en betydelig nemmere at lave den implementering, og nok den jeg umiddelbart vil anbefale dig at kigge på.
Der findes en udemærket introduktion til det her:
http://devzone.zend.com/article/1304

Eller har google også en masse (søg på 'mysql full-text' eller lign.)

Men om du har mod på det, afhænger af om du er villig til at bruge tiden på det :) Men det kan hurtigt give en fordel i forhold til de LIKE statements du bruger nu.
Avatar billede jakl2 Nybegynder
25. marts 2010 - 15:02 #5
Tusind tak..

Jeg bliver nødt til at have mod på det :)
Avatar billede intenz Novice
25. marts 2010 - 15:03 #6
I sidste ende er det selvfølgelig en afvejning af hvor meget tid der skal bruges på det, i forhold til den forbedring det giver. Hvis du syntes at hastigheden er fin med de ændringer du har lavet indtil videre, kan du selvfølgelig også bare stoppe her.

Så kan man gå tilbage og implementere det andet hvis/når der bliver behov for det.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester